题目大意:
中文题,题意是求有几个不连通块。
解题思路 :
很简单的并查集问题,我当初喜欢把并查集必须的这个find操作叫做“找爹”,我们找到顶点的“爹”们,然后看有多少个不同的“爹”,假如有n个不同的“爹”,则最少需要n-1条道路。
路径压缩这个操作,我以前喜欢写成
int get(int a){
if (x==f[x]) return x;
else f[x]=get(f[x]);
return x;
}
然后发现这么写容易爆栈。
我现在改成这么写
int get(int a){
while (x!=f[x]) x=f[x];
return f[x];
}
下面是代码:
#include<cstdio>
#include<cstring>
#include<cmath>
#define LL long long
#define db double
using namespace std;
int f[1010];
int get(int x){
if (f[x]==x) return x;
else f[x]=get(f[x]);
return f[x];
}
void merge(int a,int b){
a=get(a); b=get(b);
if (a>b) f[a]=b;
else if (a<b) f[b]=a;
}
int main(){
int n,m,res,a,b;
while (scanf("%d",&n)!=EOF && n!=0) {
for (int i=0;i<=n;i++) f[i]=i;
scanf("%d",&m);
for (int i=0;i<m;i++) {
scanf("%d%d",&a,&b);
merge(a,b);
}
res=0;
for (int i=1;i<=n;i++)
if (f[i]==i) res++;
printf("%d\n",res-1);
}
return 0;
}