2sat题目,正确理解2sat即可。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxn=(1e4+9)*2; int n,m; int a[maxn][2]; int dfn[maxn],low[maxn],stack[maxn],instack[maxn],s[maxn],un[maxn]; int count,top,con; int head[maxn<<1],lon; struct { int next,to; }e[maxn*100]; void edgeini() { memset(head,-1,sizeof(head)); lon=-1; } void edgemake(int from,int to) { e[++lon].to=to; e[lon].next=head[from]; head[from]=lon; } void make(int from,int tmp,int to) { if(a[from][tmp]==a[to][0]) edgemake(from*2-tmp,to*2); else if(a[from][tmp]==a[to][1]) edgemake(from*2-tmp,to*2-1); else edgemake(from*2-tmp,from*2-(tmp^1)); } void built(int from,int tmp,int to) { if(a[from][tmp]==a[to][0]) edgemake(from*2-tmp,to*2-1); else if(a[from][tmp]==a[to][1]) edgemake(from*2-tmp,to*2); } void tarjan(int t) { dfn[t]=low[t]=++count; instack[t]=1; stack[++top]=t; for(int k=head[t];k!=-1;k=e[k].next) { int u=e[k].to; if(dfn[u]==-1) { tarjan(u); low[t]=min(low[t],low[u]); } else if(instack[u]) low[t]=min(low[t],dfn[u]); } if(dfn[t]==low[t]) { ++con; while(1) { int u=stack[top--]; instack[u]=0; s[u]=con; if(u==t) break; } } } void tarjan() { memset(dfn,-1,sizeof(dfn)); memset(instack,0,sizeof(instack)); count=top=con=0; for(int i=1;i<=n+n;i++) if(dfn[i]==-1) tarjan(i); } bool chk() { for(int i=1;i<=n+n;i+=2) if(s[i]==s[i+1]) return false; return true; } void solve() { tarjan(); bool ans=chk(); if(ans) printf("yes\n"); else printf("no\n"); } int main() { // freopen("in.txt","r",stdin); int T,cas=0; scanf("%d",&T); while(T--) { edgeini(); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&a[i][0]); if(a[i][0]==3) a[i][1]=1; else a[i][1]=a[i][0]+1; } for(int k=1,from,to,w;k<=m;k++) { scanf("%d%d%d",&from,&to,&w); if(w==0) { make(from,0,to); make(from,1,to); make(to,0,from); make(to,1,from); } else { built(from,0,to); built(from,1,to); built(to,0,from); built(to,1,from); } } printf("Case #%d: ",++cas); solve(); } return 0; }