A Bug's Life(加權並查集)
阿新 • • 發佈:2018-11-11
Description
BackgroundProfessor 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
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 }