總時間限制: 5000ms
記憶體限制: 65536kb
描述世界上有許多宗教,你感興趣的是你學校裡的同學信仰多少種宗教。
你的學校有n名學生(0 < n <= 50000),你不太可能詢問每個人的宗教信仰,因為他們不太願意透露。但是當你同時找到2名學生,他們卻願意告訴你他們是否信仰同一宗教,你可以通過很多這樣的詢問估算學校裡的宗教數目的上限。你可以認為每名學生只會信仰最多一種宗教。
輸入輸入包括多組資料。
每組資料的第一行包括n和m,0 <= m <= n(n-1)/2,其後m行每行包括兩個數字i和j,表示學生i和學生j信仰同一宗教,學生被標號為1至n。輸入以一行 n = m = 0 作為結束。
輸出對於每組資料,先輸出它的編號(從1開始),接著輸出學生信仰的不同宗教的數目上限。
樣例輸入
10 91 21 3
1 41 5
1 61 7
1 81 9
1 10
10 4
2 34 5
4 85 8
0 0
樣例輸出
case 1: 1case 2: 7
此題明顯考察集合操作,但由於n<=50000,m<=10^9,且有未知組n,m,只好用並查集解。
並查集複雜度僅有o(k),是解大資料集合問題的利器,簡單實用。
解題思想:
對於每一組資料,初始的宗教可能總數即等於人數n。每找到給出資料的已知宗教不同,合併其所在宗教,可能宗教數減一。在這裡,用並查集的「代表」方式實現查詢所在宗教。可以形象理解為a與b信仰同一宗教,b與c信仰同一宗教,則a與c信仰同一宗教。
初始化(偽**):
for(x=1->n)
x的代表=x;
查詢x的代表(偽**):
while(x!=x的代表)
return x;
查詢x,y是否在同一集合:
if(x的代表==y的代表)return 1;
else return 0;
合併x,y所在的集合:
x的代表=y的代表;
c++**:
1 #include2 #include3#define n 50010
4using
namespace
std;56
int n,m,i,x,y,po=0;7
inta[n],ans[n];89
int find(int
x)//查詢x的代表
1015
return
a[x];16}
17void unionn(int x,int
y)//合併x,y所在的集合
1823
intmain()
2432 po++;
33 ans[p]=n;//初始化ans陣列
34for(int l=1;l<=n;++l)//初始化代表陣列
3538
for(i=1;i<=m;++i)
3948
} 49}
50for(int y=1;y<=po;++y)printf("
case %d: %d\n
",y,ans[y]);//注意輸出格式
51return0;
52 }
關於宗教信仰
關於宗教信仰,到了今天我四十四歲,似乎相對看到了個輪廓。我以前,一直模糊的以為中國沒有信仰,或叫做信仰缺失。確實,在 推翻打爛了一切的東西後,似乎新中國之前信仰的馬列主義,共產主義也已經不是個信仰了,而舊中國的儒釋道當然更被打入冷宮,怎麼可能成為這個民族的主流宗教信仰。沉下心來,問問自己什麼是信仰?...
宗教信仰(並查集)
問題描述 現如今世界上有如此多的宗教信仰,要將它們所有的都保持聯絡是非常困難的。你對於找出在乙個大學裡面同學們有多少不同的宗教信仰感興趣。你知道這個大學裡面有n個學生。如果讓你去乙個乙個問每乙個學生的宗教信仰是不可能的。而且,許多學生不願意表露他們的宗教信仰。有個方法可以避免這個問題,就是去問m 0...
1526 宗教信仰
總時間限制 5000ms 記憶體限制 65536kb 描述 世界上有許多宗教,你感興趣的是你學校裡的同學信仰多少種宗教。你的學校有n名學生 0 n 50000 你不太可能詢問每個人的宗教信仰,因為他們不太願意透露。但是當你同時找到2名學生,他們卻願意告訴你他們是否信仰同一宗教,你可以通過很多這樣的詢...