最小生成树与 Kruskal 重构树

基本概念

对于有限可重集 S,称 S 中最大的数为 S瓶颈.(视语境不同也可指最小的数.)有限可重集之间可以定义大小关系:将元素分别从小到大排序,得到一个权值序列,按序列的字典序比较可重集的大小.

对于无向带权连通图 G,若 G 的一个无环连通子图 T 包含 G 的所有顶点,则称 TG 的一个生成树. T 的边权总和称作生成树的大小T 的边权瓶颈称作生成树的瓶颈T 的边权从小到大排序后得到生成树的边权序列. 对某个图 G,所有生成树中最小的称作最小生成树,瓶颈最小的称作最小瓶颈生成树,边权序列字典序最小的称作最小字典序生成树.

一般地,对于无向带权图 G(不一定连通),也可定义相应的生成森林.

最小字典序生成树

对于图 G,设生成树 T 的边权序列为 {ti},最小字典序生成树 M 的边权序列为 {mi},则 {mi} 的字典序小于等于 {ti} 的字典序. 事实上我们有更强的结论:{mi} 的每个位置都小于等于 {ti}于是能够推出,对任意 kM 让第 k 大的边取到了最小. 特别地,M 让最大的边取到了最小,也就是说,最小字典序生成树都是最小瓶颈生成树. 另外,既然每条边都取到了最小,最小字典序生成树也是最小生成树.(同时最小生成树都是最小字典序生成树,因此这两种生成树等价;这也说明所有最小生成树的边权序列都相同.)

下面我们来证明这个结论. 用反证法,设某个 i 能使 mi>ti. 现在在 M 中只保留前 i1 条边(记为 M),这会形成 ni+1 个连通块(n 为点数),将图 G 划分成 ni+1 个点集. 在 Tn1 条边中,至少要有 ni 条边是“跨点集”的(不然 T 不连通了),根据抽屉原理,至少有一条边是 t1,t2,,ti 之一(因为其他的边只有 n1i 条),设它是 tj (1ji). 现在把 tj 加进 M,这会在 M 中形成一个环. 由于 tj 是“跨点集”的(即 tj 的两个端点在 M 中不连通),环上至少有一条边不属于 M,不妨设它是 mk,这里我们有 ikn1. 因为 {ti}{mi} 都是升序,有 tjti<mimk. 于是只要把 mk 删掉,就把 M 改造成了一棵字典序更小的生成树,这就导出了矛盾.

Kruskal 算法

给定图 G,我们用贪心法求解 G 的最小字典序生成树. 首先把 G 中所有边权从小到大排序,依次将这些边加入生成树中. 对于某一条边 (u,v,w),若加入之后不形成环(即加入前 uv 不连通)则加入,否则跳过. 可用并查集维护连通性. 时间复杂度 O(mlogm),其中 m 为边数.

这样贪心有一点小问题:如果存在相等的边权,它们加入的先后顺序如何确定呢?事实上,相等的边权无论按什么顺序加入,最后都会得到一棵最小字典序生成树. 这很容易证明:考虑我们即将加入一批边权为 c 的边. 加入前的图 G 可能已经连了一些边,我们把每个连通块都看作一个点;考察全体 c,忽略在连通块内部的边(缩点后相当于自环),我们先把其他 c 都加入 G,然后取新 G 的一个生成森林即可. 显然,取的边数是确定的. 另外,加入后新形成的连通块会在下一批边加入前缩掉,所以取哪个生成森林对之后的连通性没有影响.

这段分析是重要的. 我们在矩阵树定理的相关问题中还会见到它.

这便是最小生成树的 Kruskal 算法.

最小瓶颈路

对于图 G 上的一条路径,可定义它的瓶颈为边权的瓶颈(本文中约定为最大值). 对于点 uvuv最小瓶颈路是两点间所有路径中瓶颈最小的. 最小瓶颈路可能有多个,我们通常只希望求出一条来. 下面我们证明:MG 的一个最小生成树,则 uvM 上的简单路径一定是 G 上的最小瓶颈路.

用反证法,假设 uvM 上的路径不是最小瓶颈路. 设最小瓶颈为 c. 我们把路径上最大的那条边 w(根据假设,w>c)删去,这将 M 分成两个连通块,一个包含 u,另一个包含 v. 考虑一条真正的最小瓶颈路,它从 u 走到 v 必定会跨过两个连通块,设跨过的这条边为 w,则有 wc<w. 现在把 w 加回 MM 就变成了更小的生成树,这就导出了矛盾.

因此,给定图 G,先求一棵最小生成树,再用树上倍增或树剖求路径最值,这就求出了最小瓶颈. 时间复杂度 O(mlogm+qlogn),其中 m 为边数,n 为点数,q 为询问次数.

Kruskal 重构树

参考 cqy 课件,在此表示感谢.

Kruskal 算法是对生成树性质的充分利用. 有时候我们需要记录算法过程中的某些信息,这需要Kruskal 重构树.

在算法进行过程中,Kruskal 重构树始终是一个森林(若 G 连通则最后会变成一棵树). 首先建立 n 个叶子结点,对应图 Gn 个结点. 接下来进行 Kruskal 算法,按边权升序枚举 G 的边. 当一条边 (u,v,w) 被跳过时不做操作,否则查出 uv 两点所在树的根 rurv(此时一定有 rurv),新建权值为 w 的结点 p,将 rurv 设为 p 的儿子.

这样做的正确性显然,因为在任意时刻,uv 具有相同的树根当且仅当 uv 在 Kruskal 算法中是否已经连通. 事实上,这棵重构树本身类似于一个有边权的并查集(而且可查历史版本). 只需略微调整 Kruskal 算法中的并查集,每次不把 uv 直接合并而是把它们都与新根 p 合并(注意合并方向!),就能快速查出点所在树的根.

下面给出 Kruskal 重构树的一些性质.

  • 重构树是一棵有 n 个叶子的完满二叉树(非叶子节点恰有两个儿子).

注意:整棵重构树有 2n1 个结点. 数组要开到 2 倍.

  • 非叶子结点的点权满足大根堆性质(父亲的权值大于等于左右儿子).
  • 最小生成树上 uv 的简单路径对应于重构树上叶子 u 到叶子 v 的简单路径.

这两条性质给出一种新的求最小瓶颈路的方法:在重构树上求两点的最近公共祖先,它的权值即为最小瓶颈.

例题

待续……

posted @   abcc!  阅读(98)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示