并查集--第1篇

学习并查集,这是第1篇,后续会继续补上若干文章。

 

先看代码:

 

#include <iostream>
#include <vector>
using namespace std;

class UnionFind {
private:
    int count; //连通分量个数
    vector<int> parent; //存储每个结点的父节点
    vector<int> size; // 记录每棵树的“重量”

public:
    UnionFind(int n)
    {
        count = n;
        parent.resize(n+1, 1);
        size.resize(n+1, 1);
        for (int i = 0; i <= n; ++i)
        {
            parent[i] = i;
            size[i] = 1;
        }
    }

    int Find(int x)
    {
        // 路径压缩,方法1
        while (parent[x] != x)
        {
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        return x;

        // 路径压缩,方法2
        //return parent[x] == x ? x : parent = find(parent[x]);
    }

    void Union(int p, int q)
    {
        int rootP = Find(p);
        int rootQ = Find(q);
        if (rootP == rootQ)
        {
            return;
        }

        //小树接到大树下面,较平衡
        if (size[rootP] > size[rootQ])
        {
            parent[rootQ] = rootP;
            size[rootP] += size[rootQ];
        }
        else
        {
            parent[rootP] = rootQ;
            size[rootQ] += size[rootP];
        }
        count--;

    }

    bool connected(int p, int q)
    {
        int rootP = Find(p);
        int rootQ = Find(q);
        return rootP == rootQ;
    }

    void printParent()
    {
        cout << "print parent:" << endl;
        for (auto val : parent)
        {
            cout << val << ",";
        }
        cout << endl << endl;
    }
};

int main()
{
    vector<vector<int>>  arrInput;
    vector<int> oneItem;

    oneItem.clear();
    oneItem.emplace_back(1);
    oneItem.emplace_back(2);
    arrInput.emplace_back(oneItem);

    oneItem.clear();
    oneItem.emplace_back(2);
    oneItem.emplace_back(3);
    arrInput.emplace_back(oneItem);

    oneItem.clear();
    oneItem.emplace_back(3);
    oneItem.emplace_back(4);
    arrInput.emplace_back(oneItem);

    oneItem.clear();
    oneItem.emplace_back(1);
    oneItem.emplace_back(4);
    arrInput.emplace_back(oneItem);

    oneItem.clear();
    oneItem.emplace_back(1);
    oneItem.emplace_back(5);
    arrInput.emplace_back(oneItem);

    int n = arrInput.size();
    UnionFind ufd(n);
    for (auto& edge : arrInput)
    {
        int node1 = edge[0], node2 = edge[1];

        cout << "======= for find start("<<node1<<","<<node2<<")==========" << endl;

        if (ufd.Find(edge[0]) != ufd.Find(edge[1]))
        {
            cout <<"========= for Find ======="<<endl;
            ufd.printParent();

            ufd.Union(node1, node2);
        }
        else
        {
            cout << "END ----- edge:"<< endl;;
            ufd.printParent();
            system("PAUSE");
            return 0;
        }
    }

    system("PAUSE");
    return 0;
}

 

 

======= for find start(1,2)==========
========= for Find =======
print parent:
0,1,2,3,4,5,

======= for find start(2,3)==========
========= for Find =======
print parent:
0,2,2,3,4,5,

======= for find start(3,4)==========
========= for Find =======
print parent:
0,2,2,2,4,5,

======= for find start(1,4)==========
END ----- edge:
print parent:
0,2,2,2,2,5,

 

posted @ 2021-01-19 09:15  He_LiangLiang  阅读(65)  评论(0编辑  收藏  举报