并查集算法(union-find)

来源:互联网 发布:怎么拷贝oracle数据库 编辑:程序博客网 时间:2024/06/07 15:40

就动态连通性这个场景而言,我们需要解决的问题可能是:
给出两个节点,判断它们是否连通,如果连通,不需要给出具体的路径
给出两个节点,判断它们是否连通,如果连通,需要给出具体的路径

就上面两种问题而言,虽然只有是否能够给出具体路径的区别,但是这个区别导致了选择算法的不同,本文主要介绍的是第一种情况,即不需要给出具体路径的Union-Find算法,而第二种情况可以使用基于DFS的算法。
题目1:畅通工程
题解代码:

//并查集算法#include<iostream>using namespace std;int pre[1000];int top[1000];int findtop(int x){    int r = x;    while (pre[r] != r)        r = pre[r];    //路径压缩    int i = x, tmp;    while (pre[i] != r)    {        tmp = pre[i];        pre[i] = r;        i = tmp;    }    return r;}void joinnode(int x, int y){    int topx = findtop(x);    int topy = findtop(y);    if (topx != topy)    {        pre[topx] = topy;    }}int main(){    int n, m;    int i;    int a, b;    int result = 0;    while (scanf("%d%d", &n, &m) && n)    {           for (i = 0; i<n; i++)        {            pre[i] = i;        }        for (i = 0; i<m; i++)        {            scanf("%d%d", &a, &b);            joinnode(a, b);        }        memset(top,0,sizeof(top));        for (i = 0; i<n; i++)        {            top[findtop(i)] = 1;        }        result = 0;        for (i = 0; i<n; i++)        {            if (top[i] == 1)                result++;        }        printf("%d\n", result - 1);    }    system("pause");    return 0;}
0 0