并查集学习及通用框架

通过oi-wiki学习了并查集(disjoint set union , DSU)

并查集 - OI Wiki

#include <bits/stdc++.h>
#include <numeric>
#include <vector>
using namespace std;

struct dsu {
    vector<size_t> pa , size;

    explicit dsu( size_t size_ ):pa( size_*2 ), size( size_*2 , 1 ){
        iota( pa.begin() , pa.begin()+size_ , size_);
        iota( pa.begin()+size_ , pa.end() , size_);
    }

    size_t find( size_t x ) ;
    void unite( size_t x , size_t y ) ;
    void erase( size_t x ) ;
    void move( size_t x , size_t y ) ;
};

//normal find without compressing
//size_t dsu::find ( size_t x ){ return pa[x] == x ? x : find( pa[x] ) ; }
size_t dsu::find ( size_t x ){ return pa[x] == x ? x : pa[x] = find( pa[x] ) ; } 
//路径压缩:将所有节点直接归属于根节点

//normal unite
//void dsu::unite(size_t x, size_t y){ pa[find(x)] = find(y); }
//在路径压缩可行时,启发式合并优化并没有太明显差距;
//在可持久化并查集、线段树分治 + 并查集中,一般使用只启发式合并的并查集。
void dsu::unite(size_t x, size_t y){
    x = find(x) , y = find(y) ;
    if( x == y ) return ;
    if( size[x] < size[y] ) swap( x , y ) ;
    pa[y] = x ; //core:将size小的分支根节点改为size大的分支根节点
    size[x] += size[y] ; 
}

// 创建一个副本来保存原有的树林结构,前半段的父亲为后半段对应,删除时将父亲指向自己
void dsu::erase(size_t x){
    --size[find(x)] ;
    pa[x] = x ;
}

void dsu::move(size_t x, size_t y){
    size_t fx = find(x) , fy = find(y) ;
    if( fx == fy ) return ;
    pa[x] = fy ;
    --size[fx] , ++size[fy] ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值