并查集
并查集维护一张无向图,支持以下两种操作:
1.
连接两个点
2.
查询一个点所在的连通块
并查集的两种优化方式:
路径压缩: O ( α ( n ) ) O(\alpha (n)) O(α(n))
按秩合并: O ( log n ) O(\log n) O(logn)
Part 1:图的连通性
图的遍历也可以求图的连通性,但其复杂度为 O ( n ) O(n) O(n),如果要多次修改并查询,复杂度无法承受。
例题1:[JSOI2008][luogu1197][FAIOJ102]星球大战
两种操作,删点,求全图连通块个数。
并查集只支持连边,不支持删边。所以 时 光 倒 流
这样删点就变成加点了。每加一个点都把它和已经存在的点的边连上即可。
复杂度 O ( m α ( n ) ) O(m\alpha(n)) O(mα(n))
例题2:[Corn#3][FAIOJ11012]邪恶入侵
R R R越大,由原点可到达的点就越多。
因此将每两点之间的距离排序,再将询问的 R R R排序,双指针遍历两个数组即可。
合并的同时要维护连通块的大小。
复杂度 O ( ( n 2 + q ) log n ) O((n^2+q)\log n) O((n2+q)logn)
例题3:[Corn#2][FAIOJ11007]幽香的宴会
与上题类似,将询问按 P i P_i Pi排序,将边按边权排序,双指针遍历。
当加边的时候,要维护两个连通块的前 k k k大点权。
我们直接在每个连通块的祖先处都维护一个堆,当两个连通块合并的时候,把小块中的元素依次插入大块的堆中即可。
当堆中元素达到 k k k个时,每次加入新元素时都将最小的元素弹出。
因为入堆的操作不会超过 O ( n log n ) O(n\log n) O(nlogn