2-sat [模板]
http://poj.org/problem?id=3678
典型的2-sat裸题
View Code
/*====================================================*\ | 2-sat问题:判断某个数的0或1的取值是否存在满足条件的解 \*====================================================*/ const int MM = 222222; int N, M; bool inq[MM]; int cur,cnt,belong[MM]; int stack[MM], top,dfn[MM], low[MM]; int head[MM], NE; vector<int>edge[MM]; /*====================================================*\ | a AND b = 1 <==> _a->a _b->b | a AND b = 0 <==> a->_b b->_a | a OR b = 1 <==> _a->b _b->a | a OR b = 0 <==> a->_a b->_b | a XOR b = 1 <==> _a->b a->_b _b->a b->_a | a XOR b = 0 <==> a->b _a->_b b->a _b->_a | a表示a点选1,_a表示a点选0。 \*====================================================*/ void get_data() { int i,j,k,a,b,c; char ch[10]; for(i=0;i<M;i++) { scanf("%d%d%d%s",&a,&b,&c,ch); a<<=1; b<<=1; if(ch[0]=='A') { if(c) { edge[a^1].push_back(a); edge[b^1].push_back(b); } else { edge[a].push_back(b^1); edge[b].push_back(a^1); } } if(ch[0]=='O') { if(c) { edge[a^1].push_back(b);edge[b^1].push_back(a); } else {edge[a].push_back(a^1); edge[b].push_back(b^1); } } if(ch[0]=='X') { if(c) { edge[a^1].push_back(b); edge[a].push_back(b^1); edge[b^1].push_back(a); edge[b].push_back(a^1); } else { edge[a].push_back(b); edge[a^1].push_back(b^1); edge[b].push_back(a); edge[b^1].push_back(a^1); } } } } void tarjan(int u) { int i,j,k,v; low[u]=dfn[u]=++cnt; stack[top++]=u; inq[u]=true; for(i=0;i<edge[u].size();i++) { v=edge[u][i]; if(!dfn[v]) { tarjan(v); low[u]=f_min(low[u],low[v]); } if(inq[v]) low[u]=f_min(low[u],dfn[v]); } if(dfn[u]==low[u]) { cur++; do { v=stack[--top]; belong[v]=cur; inq[v]=false; }while(u!=v); } } bool ok() { int i,j,k; memset(dfn,0,sizeof(dfn)); cnt=top=cur=0; for(i=0;i<(N<<1);i++) { if(!dfn[i]) tarjan(i); } for(i=0;i<(N<<1);i+=2) { if(belong[i]==belong[i^1]) return false; } return true; } void solve() { int i,j,k; if(!ok()) puts("NO"); else puts("YES"); }