[模版]并查集

并查集是什么

概念

并查集是个啥呀?并查集,并,查,集。合并,查找,集合。就是这样,并查集就是可以合并查找两种操作的集合。从树的角度看,并查集就是个森林,每一棵树代表一个集合。我们要干的事情就是对于一个森林集合进行合并、或者查找。

如何实现

我们如何实现判断两个元素是否在一个集合里面呢?我们知道,在同一棵树里面的所有点,都有一个共同的祖先——根结点。ok,我们只要求出两个元素的根结点, 就可以判断这两个点是否在同一个集合里了。
合并就很容易了,把其中一个根结点变成另一个根结点的孩子结点就可以了。
是不是就很容易了?

路径压缩

我们知道对于一棵树,要求一个结点的祖先,需要一层一层通过父亲结点找上去,直到那个结点没有父结点。这样需要递归很多次。查找一个元素的祖先需要的时间复杂度是O(N)。路径压缩,实际上就是在找完根结点之后,在递归回来的时候顺便把路径上元素的父亲指针都指向根结点。是记忆化的应用。这样以后,查找两个元素是不是在一个集合里时间复杂度是O(1)。

模板

我们用一个int类型的father数组来存储每一个元素的父亲结点。对于father数组的初始化是把元素father[i]初值设置为i。
查找根结点

int getfather(int v)
{
    if(father[v]==v) return v;
    //如果一个元素的父亲结点是自己,就说明它本身就是一个根结点
    father[v]=getfather(father[v]);//路径压缩,把结点的父亲改为根结点。
    return father[v];//返回值。
}

并:把两个结点并到一个集合

void un(int x,int y)
{
    int fx,fy;
    fx=getfather(x);
    fy=getfather(y);
    //找到两个结点的结点
    father[fx]=fy;
    //其中一个根结点变成另一个根结点的孩子。
}

查:两个元素是否在一个集合

bool judge(int x,int y)
{
    int fx,fy;
    fx=getfather(x);
    fy=getfather(y);
    return fx==fy;
    //如果根结点相同,返回true,代表在同一个集合。
}

并查集就是那么简单。

例题(每一题都见链接)

luoguP3366 最小生成树
题解链接:最小生成树题解by柴犬首相
luoguP3367 并查集
题解链接:并查集模板题by柴犬首相
luoguP1551 亲戚
题解链接:亲戚题解by柴犬首相

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值