1. 程式人生 > >A Bug's Life(加權並查集)

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. 題意:一共有兩種蟲子,一個男性,另一個女性,男性只能喜歡女性,同理;問是否存在同性戀; 題解:此題是典型的加權並查集,而加權並查集就是解決同一集合內元素之間的關係,我們用pre[]陣列記錄下改節點到跟節點之間的距離,若pre[i]==pre[j]),則說明i,j同性戀,反之不是(在i,j是同一個集合(有共同的跟節點)的情況下),偌i,j屬於不同的集合,則將兩個集合合併,並跟新i,j 根節點之間的距離pre[root(i)]=(abs(str[i]-str[j])+1)%2; pre[i]==0,表示與根節點同性 pre[i]==1,表示與跟節點異性
 1 #include <iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<map>
 6 #include<algorithm>
 7 typedef long long ll;
 8 const int MAXN=5e5+10;
 9 int m,n,flag;
10 int str[MAXN];
11 int pre[MAXN];
12 using namespace std;
13 void init(int l)
14 {
15     for(int i=0; i<=l; i++)
16     {
17         str[i]=i;
18         pre[i]=0;
19     }
20     return;
21 }
22 int Find(int x)
23 {
24     if(x==str[x])
25         return str[x];
26     int temp=Find(str[x]);//遞迴法求根節點並更新到根節點之間的距離
27     pre[x]=(pre[x]+pre[str[x]])%2;
28     str[x]=temp;
29     return str[x];
30 }
31 void Union(int x,int y)
32 {
33 
34     int root1=Find(x);
35     int root2=Find(y);
36     if(root1==root2)//根節點相同
37     {
38         if((pre[x]==pre[y]))//與根節點同性
39             flag=1;
40     }
41     str[root1]=root2;
42     pre[root1]=(abs(pre[x]-pre[y])+1)%2;//更新兩個根節點之間的距離
43 
44 }
45 int main()
46 {
47     int p,k,u,r=1,l;
48     cin>>m;
49     while(m--)
50     {
51 
52         flag=0;
53         cin>>l>>k;
54         init(l);
55         for(int i=1; i<=k; i++)
56         {
57             scanf("%d%d",&p,&u);
58             if(flag)
59                 continue;
60             Union(p,u);
61         }
62         printf("Scenario #%d:\n",r++);
63         if(flag) printf("Suspicious bugs found!\n");
64         else printf("No suspicious bugs found!\n");
65         printf("\n");
66 
67     }
68     return 0;
69 }