并查集模板

简介

并查集是一种数据结构,用于处理一组不相交的集合的 合并查询 问题

它支持两种操作:

  • 查找(Find):确定某个元素处于哪个子集

  • 合并(Union):将两个子集合并成一个集合

实现

初始化

void make_set(int siz)
{
    for(int i = 1; i <= siz; i++){
        fa[i] = i;
        rk[i] = 0;
    }
}

查找

int find_set(int x)
{
    if(x == fa[x])
        return x;
    else
        return find_set(fa[x]);
}

这样虽然能达成目的但效率显然太低,我们可以将路径上的每个节点直接连接到根上,这就是 路径压缩

int find_set(int x)
{
    if(x != fa[x])
        fa[x] = find_set(fa[x]);
    return fa[x];
}

合并

void union_set(int x, int y)
{
    int u = find_set(x);
    int v = find_set(y);
    if(u == v)
        return;
    fa[u] = v;
}

在合并操作中我们也有优化方法 按秩合并 ,我们在每个节点上维护一个秩 rk[x] 用于表示表示该节点的高度,在合并时让具有较小秩的根指向较大秩的根

void union_set(int x, int y)
{
    int u = find_set(x);
    int v = find_set(y);
    if(u == v)
        return;
    if(rk[u] > rk[v]) {
        fa[v] = u;
    }else{
        fa[u] = v;
        if(rk[u] == rk[v])
            rk[v]++;
    }
}

完整模板

const int MAX_N = 10000 + 5;
int fa[MAX_N];
int rk[MAX_N];

void make_set(int siz)
{
    for(int i = 1; i <= siz; i++) {
        fa[i] = i;
        rk[i] = 0;
    }
}

int find_set(int x)
{
    if(x != fa[x])
        fa[x] = find_set(fa[x]);
    return fa[x];
}

void union_set(int x, int y)
{
    int u = find_set(x);
    int v = find_set(y);
    if(u == v)
        return;
    if(rk[u] > rk[v]) {
        fa[v] = u;
    }else{
        fa[u] = v;
        if(rk[u] == rk[v])
            rk[v]++;
    }
}

原文链接: https://www.cnblogs.com/tttkf/p/15758735.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    并查集模板

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/182937

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 上午10:19
下一篇 2023年2月12日 上午10:19

相关推荐