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 }
 
 

猜你喜欢

转载自www.cnblogs.com/moomcake/p/9807077.html