http://poj.org/problem?id=2492
种类并查集就是多维护了一个dis数组 表示当前元素与该点所在集合代表元素的关系 在压缩路径和合并时单独维护一下即可
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2e3+10;
const int maxm=1e6+10;
int f[maxn],dis[maxn];
int n,m;
int getf(int p)
{
int res;
if(f[p]==p){
return p;
}
else{
res=getf(f[p]);
dis[p]=(dis[p]+dis[f[p]])%2;
f[p]=res;
return res;
}
}
bool unite(int u,int v)
{
int fu,fv;
fu=getf(u),fv=getf(v);
if(fu!=fv){
f[fv]=fu;
dis[fv]=(dis[u]+dis[v]+1)%2;
return 1;
}
else{
if(dis[u]!=dis[v]) return 1;
else return 0;
}
}
int main()
{
int t,cas,i,u,v,flag;
scanf("%d",&t);
for(cas=1;cas<=t;cas++){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
f[i]=i,dis[i]=0;
}
flag=1;
for(i=1;i<=m;i++){
scanf("%d%d",&u,&v);
if(!unite(u,v)){
flag=0;
}
}
printf("Scenario #%d:\n",cas);
if(flag){
printf("No suspicious bugs found!\n");
}
else{
printf("Suspicious bugs found!\n");
}
printf("\n");
}
return 0;
}