并查集的使用(1)

来源:互联网 发布:崩坏3矩阵难度 编辑:程序博客网 时间:2024/05/22 10:37

题目网址:畅通工程

题目分析:抽象成在一个图查找连通分量(彼此相连的节点的集合)的个数,求出个数之后-1,就是我们需要的答案。

#include<iostream>using namespace std;int parent[1001];int findroot1(int x){//不带路径压缩的递归查找双亲节点的根节点if (parent[x] == x)return x;elsereturn findroot1(parent[x]);}int findroot2(int x){int ret;while (parent[x] != x)x = parent[x];//当前节点为非根节点则一直查找其双亲节点ret = x;return ret;}int findroot(int x){if (parent[x] != x)parent[x] = findroot(parent[x]);//当前节点的根节点设置成查找返回的根节点的编号return parent[x];}int findroot3(int x){int ret;int tmp = x;while (parent[x] != x)x = parent[x];ret = x;//采用的是x = tmp;while (parent[x] != x){int t = parent[x];parent[x] = ret;x = t;}return ret;}void merge(int a, int b)/*合并a和b*/{a = findroot(a);b= findroot(b);//可以试试findroot1、2、3if (a != b){parent[a] = b;//sum[b] += sum[a];/*如果需要统计集合中的元素可以在设置一个sum数组,合并集合中元素个数*/}}int main(){int n, m;while (cin >> n&&n){cin >> m;for (int i = 1; i <= n; i++){//初始化不能少,初始的时候每个节点都是孤立的集合,即所在集合只有一个节点,本身即为根节点parent[i] = i;}while (m--){int a, b;cin >> a >> b;merge(a, b);}int ans = 0;for (int i = 1; i <= n; i++){if (parent[i] == i)ans++;//统计集合的数目}cout << ans - 1 << endl;}return 0;}