You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
论述并查集的文章[经典]
|
|
|
|
|
https://www.cnblogs.com/zhxmdefj/p/11117791.html
|
|
|
|
|
|
|
|
|
|
一、并查集
|
|
|
|
|
(1)hdu1232 城镇交通
|
|
|
|
|
[https://www.luogu.com.cn/problem/P1536] 是同一个题
|
|
|
|
|
知识点: 并查集初始化,递归查询并压缩路径,并查集合并,计算最终有多少个并查集等知识点,别忘了集合数量减1是答案。
|
|
|
|
|
|
|
|
|
|
(2)poj1611 感染的学生
|
|
|
|
|
知识点:
|
|
|
|
|
.需要记录每个集合中的元素个数,如果两个集合合并,还需要同时修改最终集合的个数值。
|
|
|
|
|
.注意初始化时也需要将每个集合的初始值设置为1
|
|
|
|
|
.知道了按秩合并并不是必须要学习的,因为按路径压缩的方法也是一样可以保持集合元素个数的。按秩合并代码较长,不方便记忆,OI一般不考。
|
|
|
|
|
.如果使用递归可能会造成爆栈,可以使用循环的方式进行替换递归的方法,但似乎用的不多。
|
|
|
|
|
.递归压缩路径是在查询时进行的,按秩合并是在合并时将小树加到大树中。
|
|
|
|
|
|
|
|
|
|
二、带权并查集
|
|
|
|
|
.每个节点都记录的是与父节点之间的权值,那么在Find的路径压缩过程中,权值也应该做相应的更新,因为在路径压缩之前,
|
|
|
|
|
每个节点都是与其父节点链接着,那个Value自然也是与其父节点之间的权值
|
|
|
|
|
|
|
|
|
|
向量偏移法
|
|
|
|
|
路径压缩
|
|
|
|
|
int FindSet(int x) {
|
|
|
|
|
if (x == parent[x]) return x;
|
|
|
|
|
else {
|
|
|
|
|
int t = parent[x]; //记录原父节点编号
|
|
|
|
|
parent[x] = FindSet(parent[x]); //父节点变为根节点,此时value[x]=父节点到根节点的权值
|
|
|
|
|
value[x] += value[t]; //当前节点的权值加上原本父节点的权值
|
|
|
|
|
return parent[x]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
黄海解读:其实这个FindSet因为是递归,所以肯定执行多次,也就是说value[x]是要被叠加多次,比如 C->B->A三个元素 权值为1,2,
|
|
|
|
|
表示C到B的权值是1,B到A的权值是2。现在进行FindSet,就是查询C的祖先了,那么C就会被执行一次FindSet(C),找到了B,B也需要执行
|
|
|
|
|
一次FindSet(B)找到了A,A也需要执行一次FindSet(A),发现结果是自己,开始回复B,B知道了自己的祖先是A,修改自己的祖先,然后告诉
|
|
|
|
|
了C,C修改了自己的祖先。
|
|
|
|
|
其实,在上面的递归过程中,权值也会一并变化,将上面的修改一下:
|
|
|
|
|
|
|
|
|
|
.在两个并查集做合并的时候,权值也要做相应的更新,因为两个并查集的根节点不同
|
|
|
|
|
int xRoot = FindSet(x);
|
|
|
|
|
int yRoot = FindSet(y);
|
|
|
|
|
if (xRoot != yRoot){
|
|
|
|
|
parent[xRoot] = yRoot;
|
|
|
|
|
value[xRoot] = value[y] + s - value[x];
|
|
|
|
|
}
|
|
|
|
|
不懂看图:https://img2018.cnblogs.com/blog/1536438/201907/1536438-20190701134930241-1566925104.png
|
|
|
|
|
|
|
|
|
|
(1) hdu3038
|
|
|
|
|
.权值的变化方法
|
|
|
|
|
parent[xRoot] = yRoot;
|
|
|
|
|
value[xRoot] = value[y] + s - value[x];
|
|
|
|
|
.由于是区间和,需要有一点技巧,就是开闭区间,一般采用l--,然后左开右闭的方法
|
|
|
|
|
|
|
|
|
|
阅读材料:
|
|
|
|
|
https://blog.csdn.net/qq_43591839/article/details/101348031
|
|
|
|
|
https://blog.csdn.net/niushuai666/article/details/6981689
|
|
|
|
|
|