B - 宗教信仰
问题描述
世界上有许多宗教,你感兴趣的是你学校里的同学信仰多少种宗教。 你的学校有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
Hint
Huge input, scanf is recommended.
14‘
并查集的应用 事实证明并查集初始化还是i最合适,哪怕统计的时候麻烦一点而已
import java.util.Scanner;
public class Main{
static int p[];
static int find(int n) {
if(p[n]==n) return n;
return p[n] = find(p[n]);
}
static void link(int a,int b) {
int x = find(a);
int y = find(b);
if(x>y) p[x] = y;
else p[y] = x;
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
int cs = 0;
while(sc.hasNext()) {
cs++;
int n = sc.nextInt();
int m = sc.nextInt();
if(n==0&&m==0) break;
p = new int[n+1];
for (int i = 0; i < p.length; i++) {
p[i] = i;
}
int a,b;
while(m-- !=0) {
a = sc.nextInt();
b = sc.nextInt();
link(a,b);
}
int ans[] = new int[n+1];
int res = 0;
for (int i = 1; i < p.length; i++) {
ans[find(i)] = 1;
}
for (int i = 1; i < ans.length; i++) {
if(ans[i]!=0) res++;
}
System.out.println("Case "+cs+": "+res);
}
}
}