Poj 2492 A Bug's Life

题目大意:输入一个数t,表示测试组数。然后每组第一行两个数字n,m,n表示有n只昆虫,编号从1—n,m表示下面要输入m行交配情况,每行两个整数,表示这两个编号的昆虫为异性,要交配。要求统计交配过程中是否出现冲突,即是否有两个同性的昆虫发生交配。

思路:并查集,和1703几乎一样的思路。

#include <iostream>
using namespace std;
#include <memory.h>
#include <stdio.h>
// Model 1
const int MAXSIZE = 2010;
int rank[MAXSIZE];//rank[x]表示x的秩
int parent[MAXSIZE];
int n;//集合元素,从1到n
int m;
int opposite[MAXSIZE];
/* 查找x元素所在的集合,回溯时压缩路径*/
int FindSet(int x) {
	if (x!=parent[x])
		parent[x]=FindSet(parent[x]);
	return parent[x];
}
//Union按秩合并,即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小
//通过秩rank的大小来衡量元素的多少
void Union(int root1, int root2) {
	int x=FindSet(root1),y=FindSet(root2);
	if (x==y)
		return;
	if (rank[x]>rank[y])
		parent[y]=x;
	else {
		parent[x]=y;
		if (rank[x]==rank[y])
			++rank[y];
	}
}
void Initialization() {
	int i;
	memset(rank,0,sizeof(rank));
	memset(opposite,0,sizeof(opposite));
	for (i=1;i<=n;i++)
		parent[i]=i;
}
int main()
{
	int case_num,case_ctr,i,j;
	int flag;
	int x,y;

	scanf("%d",&case_num);
	for (case_ctr=1;case_ctr<=case_num;case_ctr++) {
		flag=1;
		scanf("%d%d",&n,&m);
		Initialization();
		for (i=0;i<m;i++) {
			scanf("%d%d",&x,&y);
			if (flag==1) {
				if (FindSet(x)==FindSet(y))
					flag=0;
				if (opposite[x]==0&&opposite[y]==0) {
					opposite[x]=y;
					opposite[y]=x;
				}
				else if (opposite[x]==0) {
					opposite[x]=y;
					Union(x,opposite[y]);
				}
				else if (opposite[y]==0) {
					opposite[y]=x;
					Union(y,opposite[x]);
				}
				else {
					Union(x,opposite[y]);
					Union(y,opposite[x]);
				}
			}
		}
		printf("Scenario #%d:\n",case_ctr);
		if (flag==1) 
			printf("No suspicious bugs found!\n");
		else
			printf("Suspicious bugs found!\n");
		printf("\n");
	}
	return 0;
}


你可能感兴趣的:(Poj 2492 A Bug's Life)