poj 2492 A Bug's Life(带权并查集)

题目链接:http://poj.org/problem?id=2492

用 0 1表示两种性别

用sum[i]表示节点i到根节点的距离,f[i]记录i的根节点。

f[rb]=ra;
带权路径压缩:sum[rb]=(sum[a]-sum[b]+1)%2;


#include<iostream>
#include<cstdio>
#include<cstring>
#include<math.h>
#include<algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=2005;
int T,n,m;
int f[maxn],sum[maxn];

void Make_Set(){
	for(int i=1;i<=n;i++)
		f[i]=i,sum[i]=0;
}

int find(int x){
	if(f[x]!=x){
		int tmp=f[x];
		f[x]=find(f[x]);
		sum[x]=(sum[tmp]+sum[x])%2;
	}
	return f[x];
}

bool Union(int a,int b){
	int ra=find(a);
	int rb=find(b);
	if(ra==rb&&sum[a]==sum[b])
		return false;
	f[ra]=rb;
	sum[ra]=(sum[b]-sum[a]+1)%2;
	return true;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
#endif
	int cas=1;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		Make_Set();
		bool flag=true;
		int a,b;
		while(m--){
			scanf("%d%d",&a,&b);
			if(!flag) continue;
			if(!Union(a,b)) flag=false;
		}
		printf("Scenario #%d:\n",cas++);
		if(!flag) printf("Suspicious bugs found!\n");
		else printf("No suspicious bugs found!\n");
		putchar(10);
	}
	return 0;
}


你可能感兴趣的:(poj 2492 A Bug's Life(带权并查集))