算法导论学习—— 23章 最小生成树
最小生成树的形成
采用贪心算法生成最小生成树。考虑这样一个集合
A
A
A,它是一个最小生成树的真子集。每次向
A
A
A中增加边,使得
A
A
A保持为一个最小生成树的真子集,直到加入一条边后
A
A
A也是一个最小生成树。我们称这样的边为安全边。
下面证明这样的定理:对于包含于一个最小生成树的边集合
A
A
A,
(
S
,
V
−
S
)
(S,V-S)
(S,V−S)是尊重
A
A
A的一个切割(A中的边都不横跨切割)。横跨切割的最小权值的边是
A
A
A的安全边。
证明如下:
对于横跨切割的最小权值边
(
u
,
v
)
(u,v)
(u,v),选取一个最小生成树
T
T
T,假设
(
u
,
v
)
(u,v)
(u,v)不在
T
T
T中。则在
T
T
T中必有一个横跨切割的边
(
x
,
y
)
(x,y)
(x,y),且
(
u
,
v
)
(u,v)
(u,v)的权值不大于
(
x
,
y
)
(x,y)
(x,y)。先构造边集合
T
′
=
T
−
(
x
,
y
)
∪
(
u
,
v
)
T'=T-{(x,y)}\cup{(u,v)}
T′=T−(x,y)∪(u,v),
T
′
T'
T′也是一个生成树,且
W
(
T
′
)
=
W
(
T
)
−
w
(
x
,
y
)
+
w
(
u
,
v
)
≤
W
(
T
)
W(T')=W(T)-w(x,y)+w(u,v)\leq W(T)
W(T′)=W(T)−w(x,y)+w(u,v)≤W(T)。则
T
′
T'
T′也是一个最小生成树。又
A
∈
T
A\in T
A∈T,
(
u
,
v
)
∉
A
(u,v)\notin A
(u,v)∈/A,
A
∈
T
′
A\in T'
A∈T′,
A
∪
(
u
,
v
)
∈
T
′
A\cup{(u,v)}\in T'
A∪(u,v)∈T′,即
(
u
,
v
)
(u,v)
(u,v)是
A
A
A的安全边。
因此,每次将图作满足
A
A
A的划分,找到横跨切割的最小权值边,加入
A
A
A,直到
A
A
A是一个生成树,最小生成树即可构造完成。
Kruskal算法和Prim算法
Kruskal算法
该算法在所有的边中,依次寻找权值最小的边,如果加入该边后成环,说明该边不是横跨切割的边,继续寻找,直到加入该边后不成环,则找到安全边,加入 A A A中。重复以上过程,直到 A A A是一个生成树。
Prim算法
Prim算法先规定一个起始点,加入 A A A中,将 A A A中的点与其他点做切割,选取横跨划分的最小的边,加入 A A A中, A A A的节点集合更新。重复以上步骤直到 A A A是一个生成树。在实际操作中,对于每一个新加入 A A A的节点,考察它的所有边,更新可达点的最短距离,即可找到横跨切割的最小权值边。