如题:http://poj.org/problem?id=2524
最简单的并查集。
#include<iostream>
#include<algorithm>
using namespace std;
#define N 50001
using namespace std;
struct Node
{
int data; //数据域
int rank; //优先度(深度)
int parent; //集合标识
}node[N];
int get_parent(int x) //得到x元素所在的集合
{
if(node[x].parent==x)
return x;
else
return get_parent(node[x].parent);
}
void Union(int a,int b) //a所在的集合和b所在的集合合并
{
int fa,fb;
fa=get_parent(a);
fb=get_parent(b);
if(fa==fb)
return;
if(node[fa].rank>node[fb].rank) //将深度小的集合放在深度大的下面
{
node[fb].parent=fa;
if(node[fb].rank+1>node[fa].rank)
node[fa].rank=node[fb].rank+1;
}
else
{
node[fa].parent=fb;
if(node[fa].rank+1>node[fb].rank)
node[fb].rank=node[fa].rank+1;
}
}
int main()
{
int n,m;
int u=0;
int i;
while(1)
{
u++;
scanf("%d %d",&n,&m);
getchar();
if(!n)
break;
for(i=0;i<N;i++) //并查集初始化
{
node[i].rank=0;
node[i].parent=i;
node[i].data=0;
}
for(i=0;i<m;i++)
{
int stu1,stu2;
scanf("%d %d",&stu1,&stu2);
getchar();
Union(stu1,stu2);
}
int sum=0;
int religion[N];
int moni=0;
for(i=1;i<=n;i++)
religion[i]=get_parent(i);
sort(religion+1,religion+n);
for(i=1;i<=n;i++)
{
if(religion[i]!=moni) //去掉重复
{
moni=religion[i];
sum++;
}
}
cout<<"Case "<<u<<": "<<sum<<endl;
}
return 0;
}