*普通并查集

并查集:
算法过程:(路径压缩)
1.最开始每个人都是自己的父亲节点
2.递归找根节点. (非递归也可)
如果f[x] != x(不是根节点)
f[x] = getf(f[x]); -----路径压缩
否则
返回 x;
3.查询x,y是否在同一个集合.
3.1 先找出x,y所在集合的两棵树的根节点.fx,fy(擒贼先擒王原则)
3.2 判断fx == fy
3.2.1(真) 返回真.
3.2.2(假)
3.2.2.1 将fy的父节点变为fx (靠左原则)

解释:
①代码看Kursal算法模板.
②复杂度:O(logn)
数学分析:https://blog.csdn.net/wang3312362136/article/details/86475324

二.按秩合并(又称启发式合并)
思路:
给每个点一个秩,其实就是树高
每次合并的时候都用秩小的指向秩大的,可以保证树高最高为log2(n).
操作的时候,一开始所有点的秩都为1
在一次合并后,假设是点x和点y,x的秩小
当然x和y都是原来x和y所在区间的顶点
设点x秩为rank[x]
将fa[x]指向y,然后将rank[y]的与rank[x+1]取max
因为rank[x]为区间x的高,将它连向y之后,y的树高就会是x的树高+1,当然也可能y在另一边树高更高,所以取max

合并代码:

x=getf(x);y=getf(y);
if(x!=y)
{
    if(rank[x]<=rank[y])
        {
           fa[x]=y;
            rank[y]=max(rank[y],rank[x]+1);
        }
    else 
        {
              fa[y]=x;
              rank[x]=max(rank[x],rank[y]+1);
         }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值