对于怎么建边还是不太清楚
选了a,那么b c不选,所以连边
选了b或c,那么a必定不选
/* 每个点拆成i*2,i*2+1 队长选,那么队友不选 队长不选,那么队友必定要选 */ #include<bits/stdc++.h> using namespace std; #define N 6005 #define M 2000005 struct Edge{int to,nxt;}e[M<<2]; int n,m,head[N],tot; void add(int u,int v){ e[tot].to=v;e[tot].nxt=head[u];head[u]=tot++; } int dfn[N],low[N],cnt,id[N],ind,stk[N],top,ins[N]; void tarjan(int x){ low[x]=dfn[x]=++ind; stk[++top]=x;ins[x]=1; for(int i=head[x];i!=-1;i=e[i].nxt){ int v=e[i].to; if(!dfn[v]){ tarjan(v); low[x]=min(low[x],low[v]); } else if(ins[v]) low[x]=min(low[x],low[v]); } if(low[x]==dfn[x]){ int y;cnt++; do{ y=stk[top--]; ins[y]=0; id[y]=cnt; }while(x!=y); } } void init(){ cnt=tot=ind=top=0; memset(head,-1,sizeof head); memset(dfn,0,sizeof dfn); memset(low,0,sizeof low); memset(ins,0,sizeof ins); } int main(){ while(cin>>n>>m){ init(); for(int i=0;i<n;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); a<<=1,b<<=1,c<<=1; add(a^1,b),add(a^1,c); add(b^1,a),add(c^1,a); } for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); a<<=1,b<<=1; add(a,b^1),add(b,a^1); } for(int i=0;i<2*3*n;i++) if(!dfn[i])tarjan(i); int flag=0; for(int i=0;i<3*n;i++) if(id[i*2]==id[i*2+1]){ puts("no"); flag=1; break; } if(!flag)puts("yes"); } return 0; }
原文:https://www.cnblogs.com/zsben991126/p/10872517.html