算法复习——图算法篇之最小生成树之Prim算法
以下内容主要参考中国大学MOOC《算法设计与分析》,墙裂推荐希望入门算法的童鞋学习!
1. 问题背景
道路修建:需要修建道路连通城市,各道路花费不同,如下图所示。

上图中给出了一些道路修建方案,现要求连通各城市的最小花费。
这个问题本质上就是求解权重最小的连通生成子图。子图和生成子图的概念可参考算法复习——图算法篇之图的基本概念。更进一步,可以给出生成树的定义,即图 T ′ = < V ′ , E > T'=<V', E> T′=<V′,E>是无向图 G G G的一个生成子图,并且是连通、无环路的(树)。其实,我们要求的权重最小的连通生成子图一定是一棵生成树,因为如果存在环路,则至少两个城市之间连通的路至少有两条,也就是说在已经通过一条路连通的情况下再通过另一条路连通,一定产生了冗余的花费,这是没必要的。正是由于最小性的条件,我们最终的任务就变成了求解权重最小的生成树。

同时,通过上图可知,权重最小的生成树可能不唯一。
2. 问题定义
最小生成树问题(Minimum Spanning Tree Problem)
输入:
- 连通无向图 G = < V , E , W > G=<V, E, W> G=<V,E,W>,其中 w ( u , v ) ∈ W w(u, v) \in W w(u,v)∈W表示边 ( u , v ) (u, v) (u,v)的权重
输出:
- 图 G G G的最小生成树 T = < V T , E T > T=<V_T, E_T> T=<VT,ET>
m i n ∑ e ∈ E T w ( e ) s . t . V T = V , E T ⊆ E min\sum_{e \in E_T}w(e)\\ s.t.\ \ V_T=V, E_T \subseteq E mine∈ET∑w(e)s.t. VT=V,ET⊆E
3. 通用框架
需注意,通用框架不是一个具体的算法,而是求解这个最小生成树问题的总的方针策略。这个方针策略不会细节到具体的实现步骤,但是是具体算法背后最本质的思想。Prim算法和Kruskal算法都是基于这个方针策略和总体思想衍生出来的
3.1 总体框架分析
生成树是一个无向图中的连通、无环的生成子图。也就是说图中的所有顶点都会包含在这个最小生成树中,问题其实只是讨论哪些边该选择,哪些边不该选择。因此,
- 新建一个空边集A,边集A可逐步扩展为最小生成树;
- 每次向边集A中新增加一条边,并有以下约束条件:
- 需保证边集A仍是一个无环图(通用框架没有阐述如何去检验无环性,只是说应该去检验无环性);
- 需保证边集A仍是最小生成树的子集;

大家看第二个约束条件,可能会觉得这是句废话orzzz(我如果已经知道了最小生成树有那些边,我还求它干啥呢qwq)。那么问题就变成了如何保证边集A仍是最小生成树的子集呢?
3.2 相关概念
- 安全边(Safe Edge)
- A A A是某棵最小生成树T边的子集, A ⊆ T A \subseteq T A⊆T
- A ∪ ( u , v ) A \cup {(u, v)} A∪(u,v)仍是T边的一个子集,则称 ( u , v ) (u, v) (u,v)是 A A A的安全边
也就是说若每次向边集A中新增安全边,可保证边集A是最小生成树的子集。(内心os:这不是就换了一个概念,重复了一遍废话嘛嘤嘤嘤)(emmm其实真的不是,不急,且听下面分解)
于是,就可以生成通用的求解最小生成树的框架:
Generic-MST(G)
A <- 0
while 没有形成最小生成树 do
寻找A的安全边(u, v)
A <- A | (u, v) // 取并集
end
return A
那么,问题就变成了如何有效辨识安全边?
继续给出如下定义:
-
割(Cut)
- 图 G = < V , E > G=<V, E> G=<V,E>是一个连通无向图,割 ( S , V − S ) (S, V-S) (S,V

本文介绍了使用Prim算法解决最小生成树问题的方法。首先概述了最小生成树问题及其定义,随后详细讲解了Prim算法的通用框架、算法思想及其实现过程。此外,还探讨了利用优先队列进行算法优化的可能性。
最低0.47元/天 解锁文章
5414

被折叠的 条评论
为什么被折叠?



