http://www.lydsy.com/JudgeOnline/problem.php?id=1823
2-sat裸题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int N = 4010; struct edge { int nxt, to; } e[N]; int n, m, Time, cot, top, cnt = 1; int dfn[N], low[N], vis[N], st[N], belong[N], head[N]; void link(int u, int v) { e[++cnt].nxt = head[u]; head[u] = cnt; e[cnt].to = v; } void tarjan(int u) { st[++top] = u; dfn[u] = low[u] = ++Time; vis[u] = 1; for(int i = head[u]; i; i = e[i].nxt) { if(!dfn[e[i].to]) tarjan(e[i].to); if(vis[e[i].to]) low[u] = min(low[u], low[e[i].to]); } if(dfn[u] == low[u]) { ++cot; while(st[top + 1] != u) belong[st[top]] = cot, vis[st[top--]] = 0; } } int main() { int T; scanf("%d", &T); while(T--) { top = 0; cnt = 1; memset(e, 0, sizeof(e)); memset(head, 0, sizeof(head)); memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(belong, 0, sizeof(belong)); scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) { link(i, i + 3 * n); link(i + n, i + 2 * n); } for(int i = 1; i <= n; ++i) { link(i, i + 3 * n); link(i + n, i + 2 * n); } for(int i = 1; i <= m; ++i) { char c1[10], c2[10]; int x = 0, y = 0; scanf("%s%s", c1, c2); for(int i = 1; i < strlen(c1); ++i) x = x * 10 + c1[i] - '0'; for(int i = 1; i < strlen(c2); ++i) y = y * 10 + c2[i] - '0'; if(c1[0] == 'h') x += n; if(c2[0] == 'h') y += n; link(x + 2 * n, y); link(y + 2 * n, x); } bool flag = true; for(int i = 1; i <= 4 * n; ++i) if(!dfn[i]) tarjan(i); for(int i = 1; i <= 2 * n; ++i) if(belong[i] == belong[i + 2 * n]) { puts("BAD"); flag = false; break; } if(flag) puts("GOOD"); } return 0; }