In fact, I did not think of 2-sat when I first read it.
And the idea is ingenious, the programming complexity is low also I choose this question reason, in 3H4T's format is very suitable (seems to be wrong sentences. )
Specifically, because each material has two choices, it is made of full-or Han-style
Then we can consider, in the Informatics Olympiad, there are only two kinds of choices.
Looks like there's only two points and 2-sat?
Then we notice that each choice is mutually exclusive, so does this not exactly conform to the nature of 2-sat? --Each Boolean variable can only be set up or not, which is as good as the full Han style.
Okay, well, if you think about 2-sat, it's basically out of the question.
Because the topic does not need a solution, so the original prepared for the solution of the 2-sat problem of the method is not used at all
We just have to consider for each dish, if one of the dishes in this pair has been selected then another dish has to be selected then we will be in between them, the specific edge method everyone think about it, or you can see the Makegraph function in the code
So what's the last thing to do? Only need to Tarjan to the original image, and then for each material, if the full and Han type in the same SCC then bad
otherwise good
Personal feeling this problem is still good, in line with the provincial selection style
#include <iostream> #include <cstring> #include <cstdio> #include <stack> #include < Algorithm> #define MAX 2009#define Rep (i, J, K) for (int i = j; I <= K; i++) using namespace std;int next[2 * MAX], hea D[max], tot = 0, N, M, to[2 * max];int Scc[max], Dfn[max], In[max], Low[max], sccnum = 0;int dfsclock = 0, Case;stack<i nt>s;inline int Calc (char ch, int x) {return 2 * x + (ch! = ' m ');} inline void Add (int x, int y) {To[++tot] = Y;next[tot] = head[x];head[x] = tot;} inline void Makegraph () {char ch1, ch2;int num1, Num2;rep (i, 1, m) {GetChar (); scanf ("%c%d%c%d", &ch1, &num1, & ; CH2, &num2); int point1 = Calc (ch1, num1), Point2 = Calc (CH2, num2); Add (point1 ^ 1, point2); Add (point2 ^ 1, point1 );}} inline void init () {scanf ("%d%d", &n, &m); Sccnum = Dfsclock = tot = 0;while (!s.empty ()) S.pop (), memset (in, 0, sizeof (in)), memset (head, 0, sizeof (head)), memset ( SCC, 0, sizeof (SCC)), memset (low, 0, sizeof), memset (next, 0, sizeof (NEX)t)); memset (DFN, 0, sizeof (DFN)); Makegraph ();} inline void Tarjan (int x) {dfn[x] = low[x] = ++dfsclock;s.push (x); in[x] = 1;for (int i =head[x]; i; i = Next[i]) if (!dfn[ To[i]] {Tarjan (to[i]); low[x] = min (low[x], low[to[i]]);} ElseIf (In[to[i]]) low[x] = min (low[x], dfn[to[i]), if (low[x] = = Dfn[x]) {sccnum++;while (1) {int now = S.top (); Scc[now] = Sccnum;s.pop (); In[now] = 0;if (now = = x) break;}} return;} inline void work () {Rep (I, 2, 2 * n + 1) if (!dfn[i]) Tarjan (i);} inline void print () {for (int i = 2; I <= 2 * n; i + = 2) if (scc[i] = = scc[i ^ 1]) {printf ("bad\n"); return;} printf ("good\n"); return;} int main () {scanf ("%d", &case), while (case--) {init (); work ();p rint ();} return 0;}