1. 程式人生 > >HDU 1829 A Bug's Life

HDU 1829 A Bug's Life

Problem Description Background 
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs. 

Problem 

Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.

Input The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.
Output The output for every scenario is a line containing "Scenario #i:", where i is the number of the scenario starting at 1, followed by one line saying either "No suspicious bugs found!" if the experiment is consistent with his assumption about the bugs' sexual behavior, or "Suspicious bugs found!" if Professor Hopper's assumption is definitely wrong.
Sample Input 2 3 3 1 2 2 3 1 3 4 2 1 2 3 4
Sample Output Scenario #1: Suspicious bugs found! Scenario #2: No suspicious bugs found! Hint
Huge input,scanf is recommended.

本題的意思是有一些蟲子,他們都是喜歡異性的,不存在任何一隻蟲子有兩種性別,判斷是否存在雙性戀的蟲子。

例如樣例1

1 2 說明1和2不同性別

2 3 說明2和3不同性別

由此2組得知1和3同性,2另外一個性別

1 3 說明1和3不同性別,矛盾

所以NO

以下給出三組NO的較為特殊資料

4 4        5 5         6 5

1 2        1 2         1 2

2 3        4 5         3 4

3 4        2 3         4 5

1 4        3 4         2 3

              2 5         5 6

以下為程式碼

#include<stdio.h>
int root[2005];
int dis[2005];
bool tag;
int n,m;
void init(int n)
{
	for(int i=1;i<=n;i++)
	{
		dis[i]=0;
		root[i]=i;
	}
	tag=true;
}
int find(int x)
{
	if(root[x]!=x)
	{
		int ps;//根在下一步會被壓縮
		ps=root[x];
		root[x]=find(root[x]);
		dis[x]=(dis[x]+dis[ps])%2;//為了方便判斷兩點間是否不同性,可通過奇偶性判斷
	}
	return root[x];
}
void un(int x,int y)
{
	int a,b;
	a=find(x);
	b=find(y);
	if(a!=b)
	{
		root[a]=b;
		dis[a]=(1+dis[x]-dis[y])%2;//改變a的根的同時,需改變a到根的距離
	}
	find(x);//隨著a的根改變,x距離根的距離也需改變
}
int main()
{
	int t,co=0;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		init(n);
		while(m--)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			if(tag)//若已出現不同性的剩下資料只需輸入即可
				un(x,y);
			if(dis[x]==dis[y])
				tag=false;
		}
		printf("Scenario #%d:\n",++co);
		if(tag)
			printf("No suspicious bugs found!\n\n");
		else
			printf("Suspicious bugs found!\n\n");
	}
	return 0;
}