写模板, 并查集。

1: 实现路径压缩并查集,查找,合并,判同集合。
2: 获取集合大小,集合数量。
3: 增加权重,查询单个元素到集合代表元素的权重。
4: 增加获取集合中元素的功能。

以C++的三大特性之一封装来写该模块,代码量大概是90行左右。

用到的库: vector, nnumeric(iota函数)。

class DisjointSet{
public:
    DisjointSet(int sz): sz_(sz), num_sets_(sz){
        fa_.resize(sz_);
        iota(fa_.begin(), fa_.end(), 0);

        assert(use_dist_ == use_set_size_ || (use_set_size_ == true));  //节点合并时dist_的值更新必须用到set_size_,而set_size_不依赖dist_
        if (use_set_size_){
            set_size_.resize(sz_);
            fill(set_size_.begin(), set_size_.end(), 1);
        }
        if (use_dist_){
            dist_.resize(sz_);
        }
        if (use_elements_){
            elements_.resize(sz_);
            for (int i = 0; i < sz_; ++i){
                elements_[i].emplace_back(i);
            }
        }
    }

    int findSet(int x){
        if (fa_[x] == x){
            return x;
        }
        else{
            if (use_dist_){
                updateDist(x);
                return fa_[x];
            }
            return fa_[x] = findSet(fa_[x]);
        }
    }

    int getSetSize(int x){
        assert(use_set_size_ == true);
        return set_size_[findSet(x)];
    }

    int getDist(int x){
        assert(use_dist_ == true);
        updateDist(x);
        return dist_[x];
    }

    int countSets(){
        return num_sets_;
    }

    vector<int> getSetElements(int x){
        assert(use_elements_ == true);
        return elements_[findSet(x)];
    }

    bool isSameSet(int x, int y){
        return findSet(x) == findSet(y);
    }

    bool unionSet(int x, int y){
        x = findSet(x);
        y = findSet(y);
        if (x == y){
            return false;
        }
        fa_[x] = y;
        num_sets_ --;
        if (use_elements_){
            elements_[y].insert(elements_[y].end(), elements_[x].begin(), elements_[x].end());
            elements_[x].clear();
        }
        if (use_dist_){
            dist_[x] = set_size_[y];
        }
        if (use_set_size_){
            set_size_[y] += set_size_[x];
        }
        return true;
    }

private:
    vector<int> fa_;
    int sz_, num_sets_;


    vector<int> set_size_;
    vector<int> dist_;
    vector<vector<int>> elements_;

    bool use_dist_ = false;
    bool use_set_size_ = true;
    bool use_elements_ = false;


    void updateDist(int x){
        if (fa_[x] == x){
            return;
        }
        int par = fa_[x];
        fa_[x] = findSet(par);
        dist_[x] += dist_[par];
    }

};
posted @   _Yxc  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示