并查集——(四)C++ 并查集模板

推荐使用的并查集模板。

#include <vector>

template <class T>
struct _DISJOINTSET {
    /*
    当_ds[x]<0的时候,说明x的父节点是自己。同时 |_ds[x]| 表示集合内元素数量
    当_ds[x]>0的时候,表示父节点
    */
    vector<T> _ds;//并查集
    T _n;//数据容量

    _DISJOINTSET(T n) : _n(n),  _ds(n, -1) {}
  
    //查找x的父亲
    T find_root(T x) {
        if (x<0 || x>=_n || _ds[x]<0) {
            return x;
        }
        return _ds[x] = find_root(_ds[x]);
    }
 
    //建立关系
    bool union_set(T x, T y) {
        if (x<0 || x>=_n || y<0 || y>=_n) {
            return false;
        }
        x = find_root(x);
        y = find_root(y);
        if (x==y) {
            //两个已经在同一个集合
            return false;
        }
        if (_ds[x]>_ds[y]) {
            //保证不会出现单边增长
            swap(x, y);
        }
        _ds[x] += _ds[y];
        _ds[y] = x;
        return true;
    }
 
    //查找x和y是否在同一个父亲
    bool relation(T x, T y) {
        if (x<0 || x>=_n || y<0 || y>=_n) {
            return false;
        }
        return find_root(x) == find_root(y);
    }

    //数据 x 所在集合大小
    T size(T x) {
        if (x<0 || x>=_n) {
            return 0;
        }
        return -_ds[find_root(x)];
    }
};

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的老周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值