百練 2492 : A Bug's Life --並查集簡單應用
阿新 • • 發佈:2019-02-09
他說每個測試輸出兩行,其實是三行吧,否則PE.
並查集的簡單應用,類似於”發現它,抓住它”.
描述
Hopper 博士正在研究一種罕見種類的蟲子的性行為。他假定蟲子只表現為兩種性別,並且蟲子只與異性進行互動。在他的實驗中,不同的蟲子個體和蟲子的互動行為很容易區分開來,因為這些蟲子的背上都被標記有一些標號。
現在給定一系列的蟲子的互動,現在讓你判斷實驗的結果是否驗證了他的關於沒有同性戀的蟲子的假設或者是否存在一些蟲子之間的互動證明假設是錯的。
輸入
輸入的第一行包含實驗的組數。每組實驗資料第一行是蟲子的個數(至少1個,最多2000個) 和互動的次數 (最多1000000次) ,以空格間隔. 在下面的幾行中,每次互動通過給出互動的兩個蟲子的標號來表示,標號之間以空格間隔。已知蟲子從1 開始連續編號。
輸出
每組測試資料的輸出為2行,第一行包含 "Scenario #i:", 其中 i 是實驗資料組數的標號,從1開始,第二行為 "No suspicious bugs found!" 如果實驗結果和博士的假設相符,或 "Suspicious bugs found!" 如果Hopper的博士的假設是錯誤的
樣例輸入
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4
樣例輸出
Scenario #1:
Suspicious bugs found!
Scenario #2:
No suspicious bugs found!
#include <iostream>
#include <stdio.h>
using namespace std;
int _case, bug, flag, action, a, b;
int father[2100], r[2100];
//r表示和父節點的關係,0表示同性
int root(int x)
{
int temp;
if(x == father[x])
return father[x];
//路徑壓縮
temp = root(father[x]);
r[x] = (r[x]+r[father[x]]) % 2;//路徑壓縮時,修改節點和祖先的關係
father[x] = temp;
return father[x];
}
void Union(int x,int y)
{
int fx = root(x);
int fy = root(y);
if(fx != fy)
{
/*if(father[x] == fx )
cout<<"hhhhhhhh"<<endl;
else
cout<<"aaaaaaaaa"<<endl;*/
father[fx] = fy;
//歸併後修改關係
if(r[y] == 0)
r[fx] = 1 - r[x];
else
r[fx] = r[x];
}
else //已經有相同祖先
{
if(r[x] == r[y])
flag = 1;//他們是同性
}
}
int main()
{
scanf("%d",&_case);
for(int t=1;t<=_case;t++)
{
flag = 0;
printf("Scenario #%d:\n",t);
scanf("%d%d",&bug,&action);
for(int i=1;i<=bug;i++)
{
father[i] = i;
r[i] = 0;
}
while(action--)
{
scanf("%d%d",&a,&b);//蟲子編號
if(flag == 0)
Union(a,b);
}
if(flag == 1)
printf("Suspicious bugs found!\n");
else
printf("No suspicious bugs found!\n");
printf("\n");
}
return 0;
}