并查集实现代码模板

并查集实现代码模板

  1. 并查集定义

    const int MAX_N = 99999; //并查集最大数
    int par[MAX_N];
    //这个数组存放的是第i个元素的父节点 如果父节点是它本身就代表这是个元素是根节点
    int ran[MAX_N];  //记录树的高度 为了压缩路径使用
    
  2. 初始化

    void Init(int n){
        for(int i=0;i<n;i++) {
            par[i] = i; //父节点数组都是自己本身
            ran[i] = 0; //高度初始化为0
        }
    }
    
  3. 寻找根节点函数

    int find(int x) { //寻找第x个元素的根节点并返回
        if(par[x] == x)
            return x;
        else 
            return par[x] = find(par[x]); //边寻找根节点边让这个集合的元素都直接指向根节点
        //方便下一次查询  为了方便不修改相应树的高度
    }
    
  4. 合并x和y所属的集合

    void unite(int x,int y) {
        //先判断x和y的根节点是不是同一个根节点
        x = find(x); y = find(y);
        if(x == y) return ; //不需要合并
        if(ran[x] < ran[y]) {//让高度低的树附属在高度大的树上	
            par[x] = y; //x的父节点变为y
        } else {
            par[y] = x; 
            //如果x和y为根节点的树高度相等 y附属于x上 x的高度加1
            if(ran[x] == ran[y]) rank[x]++;
        }
    }
    
  5. 判断x和y是否在同一个集合

    bool same(int x,int y) {
        return find(x) == find(y);
    }
    
  6. 判断这个并查集中有几个不同的集合或者部落

    //遍历循环pare数组   如果pare[i]==i 说明这是一个独立的集合 看有几个
    int ans=0;
    //N是总数量
    for(int i=0;i<N;i++){
        if(par[i]==i) ans++;
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值