宗教信仰,並查集
問題描述
世界上有許多宗教,你感興趣的是你學校裏的同學信仰多少種宗教。 你的學校有n名學生(0 < n <= 50000),你不太可能詢問每個人的宗教信仰
因為他們不太願意透露。但是當你同時找到2名學生,他們卻願意告訴你他們是否信仰同一宗教
你可以通過很多這樣的詢問估算學校裏的宗教數目的上限。你可以認為每名學生只會信仰最多一種宗教。
Input
輸入包括多組數據。 每組數據的第一行包括n和m,0 <= m <= n(n-1)/2,其後m行每行包括兩個數字i和j,表示學生i和學生j信仰同一宗教,學生被標號為1至n。輸入以一行 n = m = 0 作為結束。
Output
對於每組數據,先輸出它的編號(從1開始),接著輸出學生信仰的不同宗教的數目上限。
Sample Input
10 9 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 10 4 2 3 4 5 4 8 5 8 0 0
Sample Output
Case 1: 1 Case 2: 7
歸類算法,並查集
簡單來說就是同樣的人放入同樣的集合,最後判斷集合的個數
這裏吐槽一下某些oj,格式錯誤也提示的是wrong answer
最後的Case寫成case導致幾個小時的歡樂時光就“pia”的沒了
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<cstdio>
#include<queue>
#include<stack>
#define Watch_RunTime 1
#if Watch_RunTime
#include <ctime>
int start_time;
#endif
#define debug 1
#define Max 3000
using namespace std;
int findRoot(int s[], int x)
{
while (s[x] >= 0)
x = s[x];
return x;
}
int main() {
{
#if debug
freopen("in.txt", "r", stdin);
#endif
#if Watch_RunTime
start_time = clock();
#endif
}
int *a;
int n, m,casee=0;
while (1)
{
cin >> n >> m;
if (m == 0 && n == 0)
break;
a = new int[n+1];
memset(a, -1, sizeof(int)*(n+1));
for (int k = 0; k < m; k++)
{
int i, j;
cin >> i >> j;
if(findRoot(a, j) != findRoot(a, i))
a[findRoot(a, j)] = findRoot(a, i);
}
int count = 0;
for (int k = 1; k <= n; k++)
{
if(a[k]==-1)
count++;
}
cout <<"Case "<<++casee<<": "<< count<<endl;
delete a;
}
{
#if debug
freopen("CON", "r", stdin);
#endif
#if Watch_RunTime
cout << "\n\n\n\n-------\n";
cout << clock() - start_time << "ms";
#endif
}
system("pause>nul");
return 0;
}
宗教信仰,並查集