1. 程式人生 > >宗教信仰,並查集

宗教信仰,並查集

NPU 導致 表示 algorithm 告訴 out art 格式 delet

問題描述

世界上有許多宗教,你感興趣的是你學校裏的同學信仰多少種宗教。
你的學校有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<vector>
#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;
}

宗教信仰,並查集