学习一发2-SAT。
orz这个blog讲得不错。
http://blog.csdn.net/jarjingx/article/details/8521690
(论tarjan到底要不要加在栈中的标记)
/* Footprints In The Blood Soaked Snow */ #include <cstdio> #include <algorithm> using namespace std; const int maxn = 2000005, maxm = maxn, maxs = 2000000; int n, m, head[maxn], cnt, dfn[maxn], low[maxn], clo, belong[maxn], tot; bool ins[maxn]; struct _edge { int v, next; } g[maxn]; struct _pos { int x, y; } p[maxm]; inline int iread() { int f = 1, x = 0; char ch = getchar(); for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1; for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0'; return f * x; } inline void add(int u, int v) { g[cnt] = (_edge){v, head[u]}; head[u] = cnt++; } int sta[maxs], top = 0; inline void tarjan(int x) { dfn[x] = low[x] = ++clo; ins[x] = 1; sta[++top] = x; for(int i = head[x]; ~i; i = g[i].next) { int v = g[i].v; if(!dfn[v]) tarjan(v), low[x] = min(low[x], low[v]); else if(ins[v]) low[x] = min(low[x], dfn[v]); } if(dfn[x] == low[x]) { tot++; while(1) { int u = sta[top--]; belong[u] = tot; ins[u] = 0; if(u == x) break; } } } inline bool check() { for(int i = (m << 1) - 1; i >= 0; i--) if(belong[i] == belong[i ^ 1]) return 1; return 0; } int main() { n = iread(); m = iread(); for(int i = 0; i < maxn; i++) head[i] = -1; cnt = 0; for(int i = 0; i < m; i++) { int x = iread(), y = iread(); if(x > y) swap(x, y); p[i] = (_pos){x, y}; } for(int i = 0; i < m; i++) for(int j = i + 1; j < m; j++) if((p[i].x < p[j].x && p[j].x < p[i].y && p[i].y < p[j].y) || (p[j].x < p[i].x && p[i].x < p[j].y && p[j].y < p[i].y)) { add(i << 1, j << 1 | 1); add(i << 1 | 1, j << 1); add(j << 1, i << 1 | 1); add(j << 1 | 1, i << 1); } for(int i = (m << 1) - 1; i >= 0; i--) if(!dfn[i]) tarjan(i); if(check()) printf("the evil panda is lying again\n"); else printf("panda is telling the truth...\n"); return 0; }