并查集的实现(维护大小版)

         这是C++算法基础-数据结构专栏的第三十篇文章,专栏详情请见此处


引入

        上次我们学习了朴素版的并查集,并且实现了合并和查找的操作以及优化方法,但有时候,某些题目会让你求某个集合的大小,朴素版的并查集就无能为力了,所以我们今天就学习能维护大小的并查集。

        维护大小版的并查集和朴素版的并查集的定义、操作和优化都是大致相同的,如果想了解具体内容,可以移步至我的这篇博客:并查集的实现(朴素版)

         在这里就不再详细讲解,只讲解主体过程qwq

        下面我们就来讲并查集的实现(维护大小版)。

过程

        例题:连通块中点的数量

        题目大意:给定n个点,要求组成无向图。现在要进行m​个操作,操作共三种:在点a和点b之间连一条边;询问点a和点b是否在同一个连通块中;询问点a所在连通块中点的数量。

        维护大小

        在上次的学习中,我们知道了在并查集合并时,除了路径压缩时一路上经过的点,部分节点没有被更新,所以只有根节点才是有用的。

        那么如果要维护大小的话,我们就可以建一个新的数组size[],用来表示当前集合中的节点个数。加上前面的分析,我们又能得出,在合并时,我们将根节点的size[]更新,查询集合的大小时,只需像查找时一样,不停寻找到根节点,并输出其size[]即可。也就是说,size[]只有根节点的有意义

        另外,初始化时,每个size[]都要赋值为1,因为每个点初始都是一个集合,大小都为1

代码

        下面给出朴素版并查集的实现代码:

int p[N],size[N];

int find(int x){
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

for(int i=1;i<=n;i++){
    p[i]=i;
    size[i]=1;
}

size[find(b)]+=size[find(a)];
p[find(a)]=find(b);
        代码解释

        第一行是存储每个节点的祖宗节点的数组和存储当前集合中的节点个数的数组;find()函数的作用是寻找根节点;for循环中的内容的作用是初始化;最后一行的作用是合并。


上一篇-并查集的实现(朴素版)    C++算法基础专栏文章    下一篇-并查集的实现(维护到祖宗节点距离版)与食物链(NOI2001)问题


每周一更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容

点个赞,关注一下呗~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值