并查集模板
递归写法
#include<cstdio>
#define maxn 1005
using namespace std;
int f[maxn],n,m,cnt;
void init(){
cnt = 0;
for(int i = 1; i <= n ; i++)
f[i] = i;
}
int getf(int x){
if(f[x] != x) f[x] = getf(f[x]);
return f[x];
}
void merge(int u,int v){
int t1 = getf(u);
int t2 = getf(v);
if(t1 != t2)
f[t2] = t1;
}
int main(){
int u,v;
while(~scanf("%d%d",&n,&m)){
init();
for(int i = 0; i < m; i++){
scanf("%d%d",&u,&v);
merge(u,v);
}
for(int i = 1; i <= n; i++)
if(f[i] == i)
cnt++;
printf("%d\n",cnt);
}
return 0;
}
循环写法
#include<cstdio>
#define maxn 1005
using namespace std;
int f[maxn],n,m,cnt;
void init(){
cnt = 0;
for(int i = 1; i <= n ; i++)
f[i] = i;
}
int getf(int x){
int r = x,t;
while(f[r] != r)
r = f[r];
while(x != r){
t = f[x];
f[x] = r;
x = t;
}
return r;
}
void merge(int u,int v){
int t1 = getf(u);
int t2 = getf(v);
if(t1 != t2)
f[t2] = t1;
}
int main(){
int u,v;
while(~scanf("%d%d",&n,&m)){
init();
for(int i = 0; i < m; i++){
scanf("%d%d",&u,&v);
merge(u,v);
}
for(int i = 1; i <= n; i++)
if(f[i] == i)
cnt++;
printf("%d\n",cnt);
}
return 0;
}