北理CS学院2015级的学长学姐们终于搬到村里了,他们住进了新的宿舍,你想知道学校给CS学院一共安排了多少宿舍,但矜持的学长学姐们是不会直接告诉你他们宿舍号的,你唯一机会是当看到两位学姐相伴而行或者两位学长相依为Gay的时候,就可以断定他们住在同一间宿舍。已知CS学院2015级共有n(n <= 50000)名同学,你看到了m(m<=n(n-1)/2)组学长学姐对,现在请问他们至多住进了多少间宿舍。
有多组数据。对于每组数据:
第一行:两个整数n和m。
以下m行:每行包含两个整数i和j,表示推断i和j住在同一间宿舍。学生编号从1到n。
输入的最后一行中,n = m = 0。
第一行:两个整数n和m。
以下m行:每行包含两个整数i和j,表示推断i和j住在同一间宿舍。学生编号从1到n。
输入的最后一行中,n = m = 0。
对于每组测试数据,输出一行,输出数据序号( 从1开始) 和宿舍的最大数量。(参见样例)
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
Case 1: 1 Case 2: 7
Huge input, scanf is recommended.
并查集水题,判断有多少个集合
#include <stdio.h>
int f[50005];
void init(int n) {
for(int i = 1; i <= n; i++) {
f[i] = i;
}
}
int getf(int v) {
if(f[v] != v) {
f[v] = getf(f[v]);
}
return f[v];
}
void merge(int u, int v) {
int t1 = getf(u);
int t2 = getf(v);
if(t1 != t2) {
f[t1] = t2;
}
}
int main() {
int n, m;
int x, y;
int Case = 1;
while(~scanf("%d %d", &n, &m) && (n+m)) {
init(n);
int ans = 0;
for(int i = 1; i <= m; i++) {
scanf("%d %d", &x, &y);
merge(x, y);
}
for(int i = 1; i <= n; i++) {
if(f[i] == i)
ans++;
}
printf("Case %d: %d\n", Case++, ans);
}
return 0;
}