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:\nSuspicious bugs found!\n\n",++Case); else printf("Scenario #%d:\nNo suspicious bugs found!\n\n",++Case); } return 0; }

 

你可能感兴趣的:(poj)