#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int f[N];
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
struct node{
int x,y;
}a[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)f[i]=i;
for(int i=0;i<m;i++){
cin>>a[i].x>>a[i].y;
}
int cnt=0;
for(int i=0;i<m;i++){
int u=find(a[i].x);
int v=find(a[i].y);
if(u!=v){
f[u]=v;
}
}
for(int i=1;i<=n;i++){
if(f[i]==i)cnt++;
}
cout<<cnt-1;
}
经典的并查集的考察,首先看见城镇以及路,就想到了图,再看问题,求还需要修建几条路使得联通,翻译为至少几条边使得各个节点连接,那么可以使用并查集,不联通就使得节点共同指向一个父节点。最后查看哪些节点也就是城镇自己指向自己,也就是与其它城镇没相连(除了共同的那个根节点),每次ans++,最后减去根节点即可

京公网安备 11010502036488号