[JSOI2010]满汉全席 -- 2-SAT
2-SAT快忘了,回忆了一下 x--->y 代表选择x必选择y
#include<iostream> #include<algorithm> #include<cstring> #include<stack> #include<cstdio> using namespace std; const int maxn = 100000; struct Node { int to; int next; }G[maxn]; int head[maxn]; int vis[maxn]; int z; void add(int be, int en) { G[++z].to = en; G[z].next = head[be]; head[be] = z; } int n, m; int get(char *cn) { int ret = 0; for (int i = 1; cn[i]; i++) { if (cn[i] >= '0' && cn[i] <= '9') { ret *= 10; ret += cn[i] - '0'; } else break; } return ret; } int dfn[maxn], clor[maxn], low[maxn]; int df, ans; stack<int>s; int tarjan(int x) { dfn[x] = low[x] = ++df; s.push(x); vis[x] = 1; for (int i = head[x]; i; i = G[i].next) { int p = G[i].to; if (!dfn[p]) { tarjan(p); low[x] = min(low[x], low[p]); } else if (vis[p]) { low[x] = min(low[x], dfn[p]); } } if (low[x] == dfn[x]) { ans++; while (1) { int c = s.top(); s.pop(); vis[c] = 0; clor[c] = ans; if (c == x) break; } } return 0; } int main() { int t; scanf("%d", &t); while (t--) { char a[100]; char b[100]; memset(head, 0, sizeof(head)); memset(clor, 0, sizeof(clor)); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); df = 0; ans = 0; z = 0; scanf("%d%d", &n, &m); for (int i = 0; i < m; i++) {//m+n,h正 scanf("%s%s", a, b); int be = get(a); int en = get(b); if (a[0] == 'm' && b[0] == 'm') { add(be, en + n);//h--m add(en, be + n);// } else if (a[0] == 'h' && b[0] == 'h') { add(be + n, en); add(en + n, be); } else if (a[0] == 'm' && b[0] == 'h') { add(be, en); add(en + n, be + n); } else if (a[0] == 'h' && b[0] == 'm') { add(be + n, en + n); add(en, be); } a[0] = 0; b[0] = 0; } for (int i = 1; i <= 2*n; i++) { if (!dfn[i]) tarjan(i); } int flag = 0; for (int i = 1; i <= n ; i++) { if (clor[i] == clor[i + n]) { flag = 1; break; } } if (!flag) printf("GOOD\n"); else printf("BAD\n"); while (s.size()) s.pop(); } return 0; }
寻找真正的热爱