并查集模板

9 篇文章 0 订阅
4 篇文章 0 订阅

并查集

无权并查集(路径压缩)

并查集(非rank优化)//注意我写的第一位不能有0哦,因为我的强迫症让我不想初始化

int fa[10005];
inline int find(int u){
    if ( 0==fa[u]) return fa[u]=u;
    int x=u,t;
    while(x!=fa[x]) x=fa[x];
    while(u!=x){ t=fa[u];fa[u]=x;u=t; }
    return x;
}
inline void un(int u,int v){
    fa[find(u)]=find(v);
}
inline bool same_r(int u,int v){
    return find(u)==find(v);
}
rank路径压缩并查集
int fa[10005];//父亲
int rank1[10005];//树的高度
inline int find(int u){
    if(fa[u]==0) return fa[u]=u;
    int x=u,y;
    while(x!=fa[x]) x=fa[x];
    while(u!=x){ y=fa[u];fa[u]=x;u=y; }
    return x;
}
inline void un(int x,int y){
    x = find(x);
    y = find(y);
    if(x==y) return;
    if(rank1[x]<rank1[y]){
        fa[x]=y;
    }else{
        fa[y]=x;
        if(rank1[x]==rank1[y]) rank1[x]++;
    }
}
inline bool same_r(int x,int y){
    return find(x)==find(y);
}

并查集维护集合信息

一个点的所在的集合信息可以即是根结点的集合信息

int fa[10005];//父亲
int rank1[10005];//树的高度
int vis[10005];//该集合节点信息

inline int find(int u){
    if(fa[u]==0) return fa[u]=u;
    int x=u,y;
    while(x!=fa[x]) x=fa[x];
    while(u!=x){ y=fa[u];fa[u]=x;u=y; }
    return x;
}
inline void un(int x,int y){
    bool flag=0;
    if(vis[x]==1 || vis[y]==1){
        flag=1;
    }
    x = find(x);
    y = find(y);
    if(flag || vis[x] || vis[y]){
        vis[x]=1;
        vis[y]=1;
    }

    if(x==y) return;
    if(rank1[x]<rank1[y]){
        fa[x]=y;
    }else{
        fa[y]=x;
        if(rank1[x]==rank1[y]) rank1[x]++;
    }
}
inline bool same_r(int x,int y){
    return find(x)==find(y);
}

带边权并查集
int fa[500000];
int sum[500000];
int find( int u ){
    if(fa[u]==u || 0==fa[u]) return fa[u]=u;
    int root=find( fa[u] );
    sum[ u ]+=sum[ fa[u] ];
    return fa[u]=root;
}
void un(int L,int R){
    int L_root=find(L);
    int R_root=find(R);
    sum[L_root]=;//使用向量加减
    fa[ L_root ] = R_root;
}
种类并查集

请添加图片描述

大小开为: 种类数*N 对每个区间都进行操作

洛谷这篇题解写得非常好,详细地说明了群系种类并查集 : 传送门

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值