在三角洲不同地区生活的人们有自己信仰的图腾,为了避免冒犯到他们,首脑们现在想知道他们最多可能有多少种图腾。但这对他们来说是件无趣的事,所以现在任务交到了你的身上。 当你看到两个地区的人们在膜拜同一外观的石像时,就可以断定他们拥有同样的图腾。已知三角洲共有n(n <= 50000)块区域,你看到了m(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
Sample Output
Case 1: 1
Case 2: 7
Hint
Huge input, scanf is recommended.
#include<stdio.h>
#define N 100000
int s[N];
int find(int c){
if(c==s[c])
return c;
else return s[c]=find(s[c]); //返回s[c]的值
}
void Union(int a,int b)//Union不是联合,而是普通的函数名,所以用大写U
{
int fx=find(a);
int fy=find(b);
if(fx!=fy) s[fy]=fx; //如果相等,则说明对应的数组已经被改,不相等,则改
};
int main(){
int a,b,n,m,i,book=0,cut=0;
while(~scanf("%d %d",&n,&m)){
if(n==0&&m==0)
break;
cut++;
for(i=1;i<=n;i++)
s[i]=i;
for(i=0;i<m;i++){
scanf("%d %d",&a,&b);
Union(a,b);
}
for(i=1;i<=n;i++)
if(s[i]==i)
book++;
printf("Case %d: %d\n",cut,book);
book=0;
}
return 0;
}