宗教信仰,并查集
问题描述
世界上有许多宗教,你感兴趣的是你学校里的同学信仰多少种宗教。 你的学校有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;
}