poj2492A Bug's Life(並查集詳解)

A Bug's Life
Time Limit: 10000MS   Memory Limit: 65536K
Total Submissions: 25418   Accepted: 8278

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.

Source

TUD Programming Contest 2005, Darmstadt, Germany

[Submit]   [Go Back]   [Status]   [Discuss]


說起這道題令我很慚愧,初學並查集,但是這道題我想了兩天時間,一直都不明白網上的高手們的題解。

可能是自己的水平真的很水。

我幾乎想放棄這道題,或者給自己一個藉口以後回來再研究但是想了一想大牛都是要堅持不懈的,而自己又在爲這個目標而奮鬥。

所以就咬着牙堅持着想。後來就~~有了這篇解題報告。。

#include<cstdio>
#include<cstring>
//using namespace std;
int f[2023],rank[2023];//rank[]表示0爲和根節點是同性,1爲和根節點是異性
void Init(int n)
{
	for(int i=0;i<=n+1;i++)
	{
		f[i] = i;
		rank[i] = 0;
	}
}
int work(int x)
{
	if(x==f[x])
		return x;
	int tem = f[x];
	int ss = rank[tem];
	f[x] = work(f[x]);
	rank[x] = rank[x]^rank[tem];  //rank[tem]是代表x的父親節點和最新的根節點的關係
									//現在知道了rank[tem]和自己跟父親的關係即右邊的rank[x],
	return f[x];				//要更新自己跟最新根節點的關係,可知這是異或的關係。
						//例如父親節點跟最新節點是1即是異性,而自己跟父親節點是0即是同性,
						//那自己跟最新節點就是1即是異性。。
						//還有三種情況可以自己列出來。。	
}									
int main()
{
	int n;
	scanf("%d",&n);
	int bugnum,ed,x,y;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&bugnum,&ed);
		Init(bugnum);
		int re = 0;
		for(int j=0;j<ed;j++)
		{
			scanf("%d%d",&x,&y);
			if(!re)
			{
				int xx = work(x);
				int yy = work(y);
				if(xx==yy && rank[x]==rank[y])
					re = 1;
				else
				{
					f[xx] = yy;
					rank[xx] = !(rank[x]^rank[y]); //這句話是將兩棵樹的根節點合起來,那本來兩棵樹的
				}						//根節點的rank[]值都是0,現在要更新xx,即xx成爲了yy的子樹
			}						//那一定要更新rank[xx]的值。本來rank[x]和rank[y]分別爲相對xx跟yy
		}							//的性別,並且x跟y是新進入的節點,所以他們是異性。
									//所以xx相對於yy的性別爲!(rank[x]^rank[y])
		if(re==1)
			printf("Scenario #%d:\nSuspicious bugs found!\n\n",i);
		else
			printf("Scenario #%d:\nNo suspicious bugs found!\n\n",i);
	}
	return 0;
}




發佈了58 篇原創文章 · 獲贊 89 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章