2026-05-18 09:22:42
最小生成树的定义
给定一个连通无向图 $G=(V,E)$ 和权重函数 $w:E rightarrow mathbb{R}$,我们希望找到图 $G$ 的一个生成树 $T$(它连接了所有的顶点)满足:$w(T)=sum_{(u,v)in T}w(u,v)$ 的值最小,那我们称 $T$ 为最小生成树。如下面连通图所示,其中加阴影的边构成一个最小生成树:

求解最小生成树
我们首先分析最小生成树问题可以采用动态规划方法求解。应用动态规划求解的问题需要包含两个基本特点:存在最优子结构与子问题重叠。
最优子结构:
最小生成树问题具备最优子结构。我们可以通过移除某条边 $(u,v)$ 从而得到两个子树 $T_1$ 与 $T_2$。实际上,$T_1$ 与 $T_2$ 分别是其对应子图 $G_1$ 与 $G_2$ 的最小生成树。因此,最小生成树问题具备最优子结构。
沿用算法导论的证明思想,我们可以采用“剪切-粘贴”方法证明:

子问题重叠:
该问题存在子问题重叠。举个最简单的例子:我们可以通过更改不同边被移除的顺序,这样我们就会得到多个重叠的子问题。
基于上述分析,我们可以采用动态规划的方法去求解最小生成树问题。但实际上最小生成树问题具备一个更强大的特性,这使得我们可以使用复杂度更低的贪心算法去求解。
与动态规划类似,贪心算法也要求问题具备最优子结构,但其最具标识性的特点是:问题的局部最优解也是全局最优解。
我们描述一个定理,它可以帮助我们通过贪心选择来得到最小生成树(更完善严谨的数学描述与证明,需要参考算法导论,这里为方便理解仅做简单的描述):
定理:给定图 $G=(V,E)$,$T$ 是图 $G$ 的最小生成树,令 $A subseteq V$,假设边 $(u,v)$ 连接着两个集合:$A$ 与 $V-A$,并且是集合 $V-A$ 中有着最小权重的边,那么边 $(u,v)$ 属于最小生成树中的边。
要证明上述定理,我们可以从假设最小生成树 $T$ 中不包含 $(u,v)$ 这条边出发,推导出矛盾。
以下图最小生成树 $T$ 为例,设橙色结点属于集合 $A$,白色结点属于 $V-A$。$u$ 与 $v$ 之间以虚线连接,注意 $(u,v)$ 就是我们在定理中描述的,它满足两个性质。在我们的假设中,它不属于最小生成树的边。首先,必定至少存在一条边横跨集合 $A$ 与 $V-A$(因为两个集合之间连接起来,肯定需要一些过渡边),我们可以假设这条边就是 $(x,y)$。此时如果我们把 $(x,y)$ 从 $T$ 的边中给踢出去,而把 $(u,v)$ 加进来,就会得到一颗新的生成树 $T^{prime}=T-{(x,y) } cup {(u,v) }$,由于 $w(T^{prime}) < w(T)$ 与 $T$ 是最小生成树矛盾,得证。

Kruskal 算法与 Prim 算法
上述的分析为我们指明了贪心选择的关键点在于:如果选择 $(u,v)$,它要横跨集合 $A$ 与 $V-A$,并且是集合 $V-A$ 中权重最小的边。基于这种通用算法的思想,Kruskal 与 Prim 是具体的实现。
Kruskal 算法:
Kruskal 算法的过程如下所示:
注意,这里的实现会用到并查集这一数据结构。如果采用并查集实现,时间复杂度为 $O(Elg V)$。

Prim 算法:
Prim 算法的过程如下所示:
一般我们采用二叉最小堆来实现优先队列,此时 Prim 算法的时间复杂度为 $O(Elg V)$。如果使用斐波那契堆来实现优先队列,则算法复杂度将会改进到 $O(E+Vlg V)$。

以上就是关于最小生成树的学习笔记,包括最小生成树的定义、求解方法以及 Kruskal 算法和 Prim 算法的具体实现。