HDU 3062 Party 2-sat
http://acm.hdu.edu.cn/showproblem.php?pid=3062
这个题最大组大的优点就是汉语题目,WKK;
说的2-sat,但是只输出 yes/no,写完tarjan就可以得出答案了,还不是很完整的2-sat...
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define Min(a,b)a<b?a:b #define nMAX 2004 #define mMAX 2000016 using namespace std; int head[nMAX],dfn[nMAX],low[nMAX],sta[nMAX],belon[nMAX]; int s_edge,dep,atype,n,top,times; bool insta[nMAX]; struct edge { int to,next; }edge[mMAX]; void addedge(int u,int v) { s_edge++; edge[s_edge].to=v; edge[s_edge].next=head[u]; head[u]=s_edge; return ; } void tarjan(int u) { dfn[u]=++times; low[u]=times; insta[u]=1; sta[++top]=u; for(int e=head[u];e;e=edge[e].next) { int v=edge[e].to; if(!dfn[v]) { tarjan(v); low[u]=Min(low[u],low[v]); } else if(insta[v]) low[u]=Min(low[u],dfn[v]); } int j; if(low[u]==dfn[u]) { atype++; do { j=sta[top--]; insta[j]=0; belon[j]=atype; }while(j!=u); } return; } bool judge() { int i; for(i=0;i<n*2-1;i+=2) { if(belon[i]==belon[i+1]) return 0; } return 1; } void init() { s_edge=0; atype=0; dep=0; top=0; times=0; memset(head,0,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(belon,0,sizeof(belon)); memset(insta,0,sizeof(insta)); return ; } int main() { int m,i; int z1,z2,d1,d2; while(~scanf("%d",&n)) { init(); scanf("%d",&m); while(m--) { scanf("%d%d%d%d",&z1,&z2,&d1,&d2); addedge(z1*2+d1,z2*2+(d2^1)); addedge(z2*2+d2,z1*2+(d1^1)); } for(i=0;i<=2*n;i++) { if(!dfn[i]) tarjan(i); } bool flag=judge(); if(flag)printf("YES\n"); else printf("NO\n"); } return 0; }