题目链接:http://poj.org/problem?id=2492
题意:给出n个人,m条关系,每条关系表示的两个人异性,判断这m条关系是否有误。
思路:带权并查集,类似poj1182,并查集的向量应用。用1表示x,y异性,0表示同性,不访用f(x,y)表示x,y的关系。容易得出f(x,z)=f(x,y)^f(y,z),之后就好做了。输入一组关系t1,t2,用r1,r2表示其祖先,若相等则查询,即f[t1]与f[t2]是否相等; 若不等,则合并,f[r2]=1^f[t1]^f[t2](手动模拟一下)。
AC代码:
1 #include<cstdio> 2 using namespace std; 3 4 int cas,n,m,root[2005],f[2005]; 5 6 int getr(int k){ 7 if(root[k]==k) return k; 8 else{ 9 int tmp=root[k]; 10 root[k]=getr(root[k]); 11 f[k]^=f[tmp]; 12 return root[k]; 13 } 14 } 15 16 int main(){ 17 scanf("%d",&cas); 18 for(int i=1;i<=cas;++i){ 19 bool flag=true; 20 scanf("%d%d",&n,&m); 21 for(int j=1;j<=n;++j) 22 root[j]=j,f[j]=0; 23 for(int j=1;j<=m;++j){ 24 int t1,t2,r1,r2; 25 scanf("%d%d",&t1,&t2); 26 if(flag){ 27 r1=getr(t1),r2=getr(t2); 28 if(r1==r2){ 29 if(f[t1]==f[t2]) 30 flag=false; 31 } 32 else{ 33 root[r2]=r1; 34 f[r2]=1^f[t2]^f[t1]; 35 } 36 } 37 } 38 printf("Scenario #%d: ",i); 39 if(flag) 40 printf("No suspicious bugs found! "); 41 else 42 printf("Suspicious bugs found! "); 43 } 44 return 0; 45 }