写好并查集的查和并两个模块后,我们考虑,每次新输入的边代表着两个节点直接有关联,我们只需要把其中一个节点置为另一个节点的子节点,就可以维护一个并查集结构。直到遍历结束,此时用一个整型变量记录剩余并查集数量。代表着类似于自治域的不连通的模块,我们只需要在这n个模块之间修n-1条路就可以使其联通,故打印n-1
#include <bits/stdc++.h> using namespace std; int father[1010]; int setcount;//记录剩余未进行合并操作的子集 void initialize(int n) { for (int i = 0; i < n; i++) { father[i] = i; } } int findele(int u) { if (u == father[u]) { //节点的下标与数组值相等,即为找到了根节点 return u; } else { father[u]=findele(father[u]);//继续向上找 return father[u]; } } void Unionele(int i, int j) { int uroot; uroot = findele(i); int vroot; vroot = findele(j); if (uroot != vroot) { setcount--; } father[vroot] = uroot; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF){ if(n==0) break; setcount = n; initialize(n+1); for(int i=0;i<m;i++){ int u,v; scanf("%d%d",&u,&v); Unionele(u,v); } printf("%d\n",setcount-1); } return 0; }