并查集相关学习笔记

并查集是一种树形数据结构,用于处理不相交集合的合并与查询问题。
它能够维护连通性和传递性,亲戚的亲戚是亲戚。

1.合并:将两个集合合并成一个
2.查询:查询元素属于哪个集合

经典应用场景:
1.朋友圈问题(判断两人是否在同一社交圈)
2.连通图问题(判断两点是否连通)
3.kruskal
4.岛屿数量问题(?)

并查集是一棵树,树的根节点代表这个集合,每个节点指向它的父亲节点。

带权并查集:带权并查集是在普通并查集的基础上,为每个节点增加一个权值,用来表示该节点到父节点或根节点的某种关系。
核心思想:除了维护集合的归属关系,还要维护集合内元素之间的相对关系。

在带权并查集中,每个点都有权值。
权值可以表示:
1.距离:节点到父节点的距离
2.关系:如食物链中的捕食关系
3.差距:如工资差距,分数差

如何在路径压缩时更改权值:
image

并查集例题:
https://www.luogu.com.cn/problem/P2024
当我们需要维护对立关系,普通的并查集难以满足要求,可以使用种类并查集

种类并查集是普通并查集的一种扩展,用于处理元素之间存在多种关系的问题。
核心思想是将每个元素查分成多个节点,每个节点代表一种状态或身份
通过合并不同状态的节点,来表达元素之间的关系

种类并查集的经典运用:二分图(两种关系) 食物链(三种关系) 多状态问题(每个元素拆成K个)

做法一:将原并查集扩大一倍规模,划分为两个种类
在同一个种类的并查集中合并,表达它们是朋友
在不同种类的并查集中合并,表达的就是:它们是敌人

先学另一道题:
https://www.luogu.com.cn/problem/P1525

这道题目不难发现需要使用贪心的思路:我们需要让危害大的犯人尽可能在两个监狱
所以可以先把犯罪队数进行排序,然后按照敌人的敌人与自己在一个监狱里的思想进行合并。

注释:如何进行合并操作?
合并操作并不是两个目前的顶点进行合并,而是将这两个当前节点的根节点但进行合并。

重新复盘:
本道题目用了“敌人的敌人就是朋友”的做法,最后判断是否处在同一个并查集来完成。

插一嘴,关于如何识别题目是可以使用并查集的:
1.时间复杂度接近\(o(n)\),所以\(n\)可能会大于等于\(1e6\)

并查集可以合并,查询连通性,动态维护(可能互斥)的关系

关于二分图:
https://www.luogu.com.cn/problem/P1525
没错,还是同样的一道题目。

不过突然发现自己的二分答案是有漏洞的,去补一下下好了。大概是要用三道黄题去确定一个自己的二分答案基础框架。
https://www.luogu.com.cn/problem/P1542
?ber也没人教过我实数二分啊啊啊
没关系,薛靴学!

最大值最小,最小值最大其实是可以比较自然地联想到二分答案的。
感觉实数二分比整数二分简单?
另外这道题目要用printf,突然想起上次考试不会使用快读输入的惨案,待会儿去学一学好了。

有意思的是,这道题目对精度的要求很高,需要使用\(long\) \(double\)
所以需要:

printf("%.Lf",ans);

关于printf的使用方式:
输入int

printf("%d",&a);

输入long long

printf("lld",&a);

输入double

printf("%f",&a);

输入char

printf("%c",&a);

注意:printf不能直接输入string,如果想输入string,要么用cin要么就用char

https://www.luogu.com.cn/problem/P1570
为何又是实数二分?
不过不太清楚check函数怎么写。
先自己想一想然后待会儿看看吧。

哦!原来式子是可以变化的!
image
那差不多就可以开始写了,写完之后去看看这种推式子的题怎么写比较好。

posted @ 2026-08-01 16:34  Baltic  阅读(13)  评论(0)    收藏  举报