算法导论-第23章-最小生成树

对于无向图 G = ( V , E ) G=(V, E) G=(V,E),存在一个能够连接所有顶点的无环子集 T ⊆ E T \subseteq E TE,由于 T T T 无环且连接所有顶点,因此 T T T 一定为一棵树,被称为生成树。无向图 G = ( V , E ) G=(V, E) G=(V,E) 的所有生成树都恰有 ∣ V ∣ − 1 |V|-1 V1 条边。设 ( u , v ) ∈ E (u, v) \in E (u,v)E 的权重为 w ( u , v ) w(u, v) w(u,v),生成树的权重为 w ( T ) = ∑ ( u , v ) ∈ E w ( u , v ) w(T)=\sum_{(u, v) \in E}w(u, v) w(T)=(u,v)Ew(u,v),所有生成树中权重最小的生成树称为最小生成树(minimum-weight spanning tree,MST)

本章将讨论解决最小生成树问题的两种算法:Kruskal算法Prim算法如果使用普通的二叉堆,这两个算法的运行时间均为 O ( E log ⁡ V ) \Omicron(E \log V) O(ElogV)。如果使用斐波那契堆,Prim算法的运行时间将改进为 O ( E + V log ⁡ V ) \Omicron(E+V\log V) O(E+VlogV)。此运行时间当 ∣ V ∣ |V| V 远小于 ∣ E ∣ |E| E 的情况下较二叉堆有很大的改进。

Kruskal算法和Prim算法都是贪心算法

23.1 最小生成树的形成

在每遍循环之前,A是某棵最小生成树的一个子集。

选择一条边 ( u , v ) (u, v) (u,v) 加入到集合 A A A 中,使得 A A A 不违反循环不变式,即 A ∪ { ( u , v ) } A \cup \{(u, v)\} A{(u,v)} 也是最小生成树的子集。由于我们可以安全的将这样的边加入到集合 A A A 中而不会破坏 A A A 的循环不变式,因此这样的边称为集合 A A A安全边

Generic-MST

循环不变式:

  • 初始化:在算法第1行之后,集合 A A A 直接满足循环不变式。
  • 保持:算法2~4行的循环通过只加入安全边来维持循环不变式。
  • 终止:所有加入到集合 A A A 中的边都属于最小生成树,因此,算法第5行所返回的集合 A A A 必然是一棵最小生成树。

关键在于如何找到一条安全边,将其加入到集合 A A A。下面就是快速找到安全边的两个算法。

23.2 kruskal算法

MST-Kruskal
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Kruskal算法的贪心策略:通过添加每次连接两个生成树的权重最小的边,从生成树(连接的组件)的森林中生长一个MST。

Kruskal’s algorithm: Grow an MS Tfrom aforest of spanning trees (connected components) by adding the edge that hasthe minimum weight and connects twospanning trees each time.

23.3 Prim算法

MST-Prim

Figure 21.5

Prim算法的贪心策略:通过添加权重最小且在部分MST和一端没有的边,从部分MST中生长成为MST。

Prim’s algorithm: Grow an MST from apartia/ MS Tby adding the edge that hasthe minimum weight and has one end in thepartial MST and one end not in each time.

posted @ 2023-06-30 21:53  gengduc  阅读(11)  评论(0编辑  收藏  举报  来源