A Bug's Life
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;
}