题意
并查集算法最后得到的集合的个数减一就是结果
传送门
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
class UnionFind {
private:
int * fa;
int size;
public:
UnionFind(int n) {
size = n;
fa = new int[n+1];
Init();
}
~UnionFind() {
delete[] fa;
}
void Init() {
for(int i = 1 ; i <= size ; i ++) {
fa[i] = i;
}
}
int Find(int x) {
if(fa[x] != x) {
fa[x] = Find(fa[x]);
}
return fa[x];
}
bool Union(int x,int y) {
int fx = Find(x);
int fy = Find(y);
if(fx != fy) {
fa[fx] = fy;
return true;
}
else {
return false;
}
}
int GetCount() {
int count = 0;
for(int i = 1 ; i <= size ; i ++) {
if(fa[i] == i) {
count ++;
}
}
return count;
}
int GetMaxSetNum() {
int maxSetNum = 0;
int * countSet = new int[size+1];
memset(countSet,0,sizeof(int)*(size+1));
for(int i = 1 ; i <= size ; i ++) {
int fi = Find(i);
countSet[fi] ++;
}
for(int i = 1 ; i <= size ; i ++) {
if(countSet[i] > maxSetNum) {
maxSetNum = countSet[i];
}
}
delete[] countSet;
return maxSetNum;
}
};
int main() {
int n,m;
while(scanf("%d %d",&n,&m) == 2) {
UnionFind uf(n);
for(int i = 1 ; i <= m ;i ++) {
int u,v;
scanf("%d %d",&u,&v);
uf.Union(u,v);
}
printf("%d\n",uf.GetCount()-1);
}
}