Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3551 Accepted Submission(s): 1154
模型一:两者(A,B)不能同时取
那么选择了A就只能选择B’,选择了B就只能选择A’
连边A→B’,B→A’
模型二:两者(A,B)不能同时不取
那么选择了A’就只能选择B,选择了B’就只能选择A
连边A’→B,B’→A
模型三:两者(A,B)要么都取,要么都不取
那么选择了A,就只能选择B,选择了B就只能选择A,选择了A’就只能选择B’,选择了B’就只能选择A’
连边A→B,B→A,A’→B’,B’→A’
模型四:两者(A,A’)必取A
连边A’→A
#include <iostream> #include <stdio.h> #include <queue> #include <stdio.h> #include <string.h> #include <vector> #include <queue> #include <set> #include <algorithm> #include <map> #include <stack> #include <math.h> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #pragma comment(linker, "/STACK:10240000000000,10240000000000") using namespace std; typedef long long LL ; const int Max_N=2008 ; const int Max_M=2000008 ; int id ; int vec[Max_N] ,mystack[Max_N] ,top; int low[Max_N] ,dfn[Max_N] ,idx ,num ; bool instack[Max_N] ; int belong[Max_N] ; //belong[i] ,i为哪个联通分量 //int sum[Max_N] ; //缩点后每个联通分量中点的个数 struct Edge{ int v ; int next ; }; Edge edge[Max_M] ; inline void add_edge(int u,int v){ edge[id].v=v ; edge[id].next=vec[u] ; vec[u]=id++ ; } void tarjan(int u){ low[u]=dfn[u]=idx++ ; mystack[++top]=u ; instack[u]=1 ; for(int e=vec[u];e!=-1;e=edge[e].next){ int v=edge[e].v ; if(dfn[v]==-1){ tarjan(v) ; low[u]=Min(low[u],low[v]) ; } else if(instack[v]) low[u]=Min(low[u],dfn[v]) ; } if(low[u]==dfn[u]){ int v ; num++ ; do{ v=mystack[top--] ; instack[v]=0 ; belong[v]=num ; // sum[num]++ ; }while(v!=u) ; } } void init(){ idx=1 ; top=-1 ; num=0 ; id=0; memset(dfn,-1,sizeof(dfn)) ; memset(vec,-1,sizeof(vec)) ; memset(instack,0,sizeof(instack)) ; // memset(sum,0,sizeof(sum)) ; } int N ; int judge(){ for(int i=1;i<=N;i++){ if(belong[i]==belong[i+N]) return 0 ; } return 1 ; } int main(){ int m ,a1, a2, c1, c2 ,wife_A ,wife_B ,hus_A ,hus_B; while(scanf("%d%d",&N,&m)!=EOF){ init() ; while(m--){ scanf("%d%d%d%d",&a1,&a2,&c1,&c2) ; a1++ ; a2++ ; wife_A=a1 ; hus_A=a1+N ; wife_B=a2 ; hus_B=a2+N ; if(c1==0&&c2==0){ add_edge(wife_A,hus_B) ; add_edge(wife_B,hus_A) ; } else if(c1==0&&c2==1){ add_edge(wife_A,wife_A) ; add_edge(hus_B,hus_A) ; } else if(c1==1&&c2==0){ add_edge(hus_A,hus_B) ; add_edge(wife_B,wife_A) ; } else if(c1==1&&c2==1){ add_edge(hus_A,wife_B) ; add_edge(hus_B,wife_A) ; } } for(int i=1;i<=2*N;i++){ if(dfn[i]==-1) tarjan(i) ; } printf("%s\n",judge()==1?"YES":"NO") ; } return 0 ; }