原来在练最小生成树的时候,用prim写过这个题目。后面发现这个题用并查集做更好。不管是时间还是占用内存都是大大优化了。
并查集实现:
每个集合用一棵“有根树”表示
定义数组 set[1..n]
set[i] = i , 则i表示本集合,并是集合对应树的根
set[i] = j, j<>i, 则 j 是 i 的父节点.
程序代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
int bin[maxn];
int find(int x)
{
int r=x;
while(r!=bin[r])
r=bin[r];
return r;
}
void merge(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa!=fb)
bin[fa]=fb;
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF&&n)
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
merge(a,b);
}
int count=-1;
for(int i=1;i<=n;i++)
{
if(bin[i]!=i)
count++;
}
printf("%d\n",count);
}
return 0;
}