poj 2492 并查集

思路:当a,b的根节点find(a)与find(b)不同时,就直接将这两个数连接起来。由于每个树的根节点的kind值一定为0,所以,对于a,b的kind值相同,我们就讲其中一个根的kind值变为1,当下次再遍历该节点的时候,a与b的kind值就会变得不同。如果a,b的kind值相同,那么就不用变。

看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Maxn 20010
using namespace std;
int set[Maxn],kind[Maxn];
int find(int x)
{
    if(x!=set[x])
    {
        int temp=set[x];
        set[x]=find(set[x]);
        kind[x]=(kind[x]+kind[temp])%2;//保证子节点与父节点的不同。
}
return set[x]; } int merg(int a,int b) { int x,y; x=find(a); y=find(b); if(x==y) { if(kind[a]==kind[b]) return 0; return 1; } set[x]=y; kind[x]=(kind[a]-kind[b]+1)%2; return 1; } int main() { int n,m,i,j,a,b,t,Case=0,flag=0; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) set[i]=i; flag=0; memset(kind,0,sizeof(kind)); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); if(!merg(a,b)) { flag=1; break; } } for(i++;i<=m;i++) scanf("%d%d",&a,&b); if(flag) printf("Scenario #%d: Suspicious bugs found! ",++Case); else printf("Scenario #%d: No suspicious bugs found! ",++Case); } return 0; }
原文地址:https://www.cnblogs.com/wangfang20/p/3200970.html