图搜索

并查集

并查集(Disjoint Set Union, DSU)维护一组互不相交的集合,支持两种操作:

  • find(x):返回 x 所在集合的代表(根)
  • union(a, b):把 ab 所在的集合合并

底层数据结构非常简洁:用一个 parent[] 数组,parent[i] 指向 i 的父节点,根节点的 parent 指向自己。

两个关键优化

朴素实现退化成链时 find 是 O(n)。两个标准优化把均摊复杂度降到几乎 O(1):

  • 路径压缩find(x) 上溯到根之后,把路径上的所有节点的 parent 直接指向根,下次访问就是 O(1)
  • 按 rank 合并:合并两棵树时,让较矮的挂到较高的下,避免树长高

两者合用,每次操作的均摊复杂度是 O(α(n)),α 是反阿克曼函数,对任何合理大小的 n 都不超过 4。

在动画里看什么

  • 红圈 是根节点;蓝色 是被高亮的节点(当前操作涉及的)
  • 节点下方的 rk 是 rank(树高近似上界)
  • union 时先各自 find 找根,根不同才会真正合并
  • find 时高亮整条上溯路径,然后路径压缩把它们一次性挂到根下,可以看到指针从一条链变成一个扇形