Introduction
当今世界上有许多不同的明星,你想知道你们学校的学生总共喜欢多少个不同的明星。
你知道你的大学里有n个学生(0 < n ≤ 50000),你问每个学生他们喜欢的明星是不可能的。此外,许多学生不好意思说出他们喜欢哪个明星。避免这些问题的一种方法是问m (0≤ m ≤ n(n-1)/2)对学生,问他们是否喜欢相同的明星(例如,他们可能知道他们是否观看同一场演出)。从这些数据中,你可能不知道每个人具体喜欢哪个明星,但你可以知道校园里最多有多少个不同的被喜欢的明星。你可以假设每个学生最喜欢的只有一个明星。
Input
输入由多组用例组成。每一种情况都以整数n和m作为的一行开始,接下来的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
output
Case 1: 1 Case 2: 7
Solution
package week3; import java.util.Scanner; class UnionFind{ private int[] id; private int[] sz; public int count; public UnionFind(int count){ this.count=count; id=new int[count]; sz=new int[count]; for(int i=0;i<count;i++){ id[i]=i; sz[i]=1; } } public int find(int x){ if(id[x]!=x){ id[x]=find(id[x]); } return id[x]; } public void union(int x,int y){ int xRoot=find(x); int yRoot=find(y); if(xRoot!=yRoot){ if(sz[xRoot]>sz[yRoot]){ id[yRoot]=xRoot; sz[xRoot]+=sz[yRoot]; }else { id[xRoot]=id[yRoot]; sz[yRoot]+=sz[xRoot]; } count--; } } } public class Main { public static void main(String[] args) { Scanner s=new Scanner(System.in); int index=1; while(true){ int n=s.nextInt();int m=s.nextInt(); if(n==0&m==0){ break; } UnionFind unionFind=new UnionFind(n); while (m--!=0){ int x=s.nextInt();int y=s.nextInt(); unionFind.union(x-1,y-1); } System.out.println("Case "+index+": "+unionFind.count); index++; } } }
Experience
第一次使用并查集,也是学到了很多。刷题必会之一。