带路径压缩的加权并查集算法

算法思想参照《algorithms》

#include <iostream>

using namespace std;

class UF
{
private:
    int N;  // 节点数
    int count; // 连通分支数
    int *id;    // 存储节点
    int *weight;    // 树权重
public:
    UF(int N);
public:
    int get_count()     // 返回连通支数
    { return count; }

    bool connected(int p, int q)    // 判断 p,q 是否处于同一分量中
    { return id[p] == id[q]; }

    int find(int p);

    void Union(int p, int q);    // 将 p 归结于 q 连通分量中

    void display();
};

UF::UF(int N):N(N)
{
    count = N;
    id = new int[N];
    weight = new int[N];
    for(int i = 0; i < N; ++i)
    {
        id[i] = i;
        weight[i] = 1;
    }
}

int UF::find(int p)
{
    while(p != id[p])
    {
        id[p] = id[id[p]];  // 实现压缩路径(压缩两个路径,当然还可以再进行嵌套,进行高度压缩)
        p = id[p];
    }
    return p;
}

void UF::Union(int p, int q)
{
    int proot = find(p);
    int qroot = find(q);

    if (proot == qroot)
        return;

    // 由权重进行归并
    if (weight[proot] < weight[qroot])
    {
        id[proot] = qroot;
        weight[qroot] += weight[proot];
    }
    else
    {
        id[qroot] = proot;
        weight[proot] += weight[qroot];
    }

    --count;
}

void UF::display()
{
    for(int i = 0; i < N; ++i)
        cout << id[i] << " ";
}

int main()
{
    UF f(10);
    f.Union(4,3);
    f.Union(3,8);
    f.Union(6,5);
    f.Union(9,4);
    f.Union(2,1);
    f.Union(8,9);
    f.Union(5,0);
    f.Union(7,2);
    f.Union(6,1);
    f.Union(1,0);
    f.Union(6,7);
    f.display();
    cout << endl << f.get_count();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/adorkable_thief/article/details/80422040
今日推荐