链接:http://acm.hdu.edu.cn/showproblem.php?pid=3715用a[i]表示a[i]对应的x[a[i]]是0,a[i]+n表示是1,则
当c[i]=0时,不能同时为0,则a[i]->b[i]+n,b[i]->a[i]+n
当c[i]=1时,a[i]->b[i],b[i]->a[i],a[i]+n->b[i]+n,b[i]+n->a[i]+n;
当c[i]=2时,a[i]+n->b[i],b[i]+n->a[i];
最后如果二分枚举深度值,要用到二分枚举
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #define N 205 #define M 10005 using namespace std; int head[2*N],t; int dfn[2*N],sc[2*N]; int stk1[2*N],stk2[2*N],cnt0,cnt1,top1,top2; int a[M],b[M],c[M]; struct node { int v,next; }; node edge[M*4]; void init() { t=0; cnt0=cnt1=0; top1=top2=0; memset(head,-1,sizeof(head)); memset(dfn,-1,sizeof(dfn)); memset(sc,-1,sizeof(sc)); } void add(int u,int v) { edge[t].v=v; edge[t].next=head[u]; head[u]=t++; } void build(int mid,int n) { int i; for(i=1;i<=mid;i++) { if(c[i]==0) { add(a[i],b[i]+n); add(b[i],a[i]+n); } else if(c[i]==1) { add(a[i],b[i]); add(a[i]+n,b[i]+n); add(b[i],a[i]); add(b[i]+n,a[i]+n); } else { add(a[i]+n,b[i]); add(b[i]+n,a[i]); } } } void gabow(int u)//gabow算法求强连通分量 { dfn[u]=cnt0++; stk1[top1++]=u; stk2[top2++]=u; int i,j,v; for(i=head[u];i>=0;i=edge[i].next) { v=edge[i].v; if(dfn[v]==-1) gabow(v); else if(sc[v]==-1) while(dfn[stk2[top2-1]]>dfn[v]) top2--; } if(stk2[top2-1]!=u) return; top2--; do { sc[stk1[--top1]]=cnt1; }while(stk1[top1]!=u); cnt1++; } int can(int mid,int n) { init(); build(mid,n); int i; for(i=0;i<2*n;i++) if(dfn[i]==-1) gabow(i); for(i=0;i<n;i++) if(sc[i]==sc[i+n]) return false; return true; } int main() { int n,m,i,j,ans,low,high,mid; int tcase; scanf("%d",&tcase); while(tcase--) { scanf("%d%d",&n,&m); for(i=1;i<=m;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]); low=1,high=m; ans=1; while(low<=high) { mid=(low+high)>>1; if(can(mid,n)) { ans=mid; low=mid+1; } else high=mid-1; } printf("%d\n",ans); } return 0; }