目录
[1.应用 Kruskal 算法求下列图的最小生成树。](#1.应用 Kruskal 算法求下列图的最小生成树。)
a.如果e是加权连通图中权重最小的边,它至少是图的一棵最小生成树的边。
b.如果e是加权连通图中权重最小的边,它必定是图的每一棵最小生成树的边。
c.如果加权连通图中每条边的权重都是互不相同的,该图必定只有一棵最小生成树。
d.如果加权连通图中每条边的权重不是互不相同的,该图必定不止有一棵最小生成树。
[3.如果有必要,要对算法 Kruskal 做什么改动,使得它可以求出任意图的最小生成森林(minimum spanning forest)?(一个最小生成森林中的树都是图的连通分量的最小生成树。)](#3.如果有必要,要对算法 Kruskal 做什么改动,使得它可以求出任意图的最小生成森林(minimum spanning forest)?(一个最小生成森林中的树都是图的连通分量的最小生成树。))
[4.对于包含负权重边的图, Kruskal 算法都能正确工作吗?](#4.对于包含负权重边的图, Kruskal 算法都能正确工作吗?)
[5.设计一个求加权连通图的最大生成树(maximum spanning tree)算法,这是一种包含最大可能权重的树。](#5.设计一个求加权连通图的最大生成树(maximum spanning tree)算法,这是一种包含最大可能权重的树。)
[6.按照不相交子集的抽象数据类型中的操作重写 Kruskal 算法的伪代码。](#6.按照不相交子集的抽象数据类型中的操作重写 Kruskal 算法的伪代码。)
[7.证明 Kruskal 算法的正确性。](#7.证明 Kruskal 算法的正确性。)
[8.对于快速求并的按大小求并版本,证明 find(x)的时间效率属于 O(log n)。](#8.对于快速求并的按大小求并版本,证明 find(x)的时间效率属于 O(log n)。)
[11.斯坦纳(Steiner)树 4 个村庄坐落在欧几里得平面上一个单位正方形的 4 个顶点上。要求用最短的公路网把它们连接起来,使得每对村庄之间都有一条连通的路径。求这样一个网络。](#11.斯坦纳(Steiner)树 4 个村庄坐落在欧几里得平面上一个单位正方形的 4 个顶点上。要求用最短的公路网把它们连接起来,使得每对村庄之间都有一条连通的路径。求这样一个网络。)
1.应用 Kruskal 算法求下列图的最小生成树。
a.


b.



2.判断正误:
a.如果e是加权连通图中权重最小的边,它至少是图的一棵最小生成树的边。
对,最小权边一定可以被 Kruskal 算法最先选中,且不会形成环,因此一定在某棵 MST 里。
b.如果e是加权连通图中权重最小的边,它必定是图的每一棵最小生成树的边。
错,反例:图有环,且环上多条边都是最小权 ,那么可以选其中任意一条,不一定要选 e。
c.如果加权连通图中每条边的权重都是互不相同的,该图必定只有一棵最小生成树。
即使有边权相同,仍然可能只有一棵 MST。比如:一个图虽然有两条边权一样,但它们不在同一个环上,不影响唯一性。
d.如果加权连通图中每条边的权重不是互不相同的,该图必定不止有一棵最小生成树。
错,即使有边权相同,仍然可能只有一棵 MST。比如:一个图虽然有两条边权一样,但它们不在同一个环上,不影响唯一性
3.如果有必要,要对算法 Kruskal 做什么改动,使得它可以求出任意图的最小生成森林(minimum spanning forest)?(一个最小生成森林中的树都是图的连通分量的最小生成树。)
不提前终止 ,遍历完所有边,只要边不形成环就加入集合。最终得到的就是最小生成森林。
4.对于包含负权重边的图, Kruskal 算法都能正确工作吗?
可以。Kruskal 算法只依赖边的大小排序,与边权是否为负无关,因此对负权图仍能正确求出最小生成树。
5.设计一个求加权连通图的最大生成树(maximum spanning tree)算法,这是一种包含最大可能权重的树。
将所有边权取反,用 Kruskal 或 Prim 求最小生成树,得到的就是原图的最大生成树;也可以直接把算法改为每次选择权值最大的安全边。
6.按照不相交子集的抽象数据类型中的操作重写 Kruskal 算法的伪代码。
算法 KRUSKAL_MST(G):
输入: 加权无向图 G = (V, E)
输出: 最小生成树的边集 MST
MST = 空集合
// 初始化:每个顶点单独成集合
for 每个顶点 v ∈ V:
MAKE_SET(v)
// 将所有边按权重 从小到大 排序
将 E 中的边按权重升序排列
// 依次遍历每条边
for 每条排序后的边 (u, v) ∈ E:
// 如果 u 和 v 不在同一个集合 → 不形成环
if FIND(u) ≠ FIND(v):
将边 (u, v) 加入 MST
UNION(u, v) // 合并两个集合
return MST
7.证明 Kruskal 算法的正确性。
k=0时,T0=∅,显然是空边集,包含在任何 MST 里。
假设 Kruskal 选的前 k 条边构成的 Tk包含在某棵最小生成树 T∗ 中。
证明k∪{e} 也包含在某棵 MST 中。
情况 1:e 已经在 T∗ 里
那直接成立,Tk+1 也在 T∗ 里。
情况 2:e 不在 T∗ 里
把 e 加入 T∗ 一定会形成一个环。
观察这个环:
e=(u,v) 是环上的一条边
在 T∗ 中,u 和 v 已有一条路径
在选 e 之前,u 和 v 属于不同连通分量(否则 Kruskal 不会选 e)
所以这条路径上一定存在一条边 f,还没有被 Kruskal 选中
因为边是从小到大处理的:w(e)≤w(f)
构造新树:T∗∗=T∗−f+e
权重:w(T∗∗)=w(T∗)−w(f)+w(e)≤w(T∗)
因为 T∗ 是 MST,等号必须成立。所以 T∗∗ 也是 MST,并且 Tk+1=Tk∪{e} 包含在 T∗∗ 中。
8.对于快速求并的按大小求并版本,证明 find(x)的时间效率属于 O(log n)。
任何一棵大小为 s 的树,高度 h 一定满足:s ≥ 2^h
用数学归纳法:
-
初始:每个点自己是一棵树h=0,s=1,1 ≥ 2⁰=1 ✔ 成立。
-
假设:两棵树满足s₁ ≥ 2ʰ¹,s₂ ≥ 2ʰ²。
-
合并(按大小,小的挂大的):不妨设 h₁ ≤ h₂。把第一棵树挂到第二棵。
- 新高度 h = max (h₁, h₂)+1 = h₂+1
- 新大小 s = s₁ + s₂ ≥ s₂ + s₂ = 2s₂
- 而 s₂ ≥ 2ʰ²
- 所以 s ≥ 2×2ʰ² = 2^(h₂+1) = 2ʰ
即:s ≥ 2ʰ 对新树也成立。
也就是h ≤ log₂n,FIND(x) 就是从 x 走到根 ,走的步数 = 树高 h,我们刚证明:h ≤ log n 。所以 FIND(x) 最坏时间 = O(log n)
11.斯坦纳(Steiner)树 4 个村庄坐落在欧几里得平面上一个单位正方形的 4 个顶点上。要求用最短的公路网把它们连接起来,使得每对村庄之间都有一条连通的路径。求这样一个网络。
在单位正方形内部添加两个夹角均为 120° 的斯坦纳点,连接 4 个顶点与这两个点,得到的斯坦纳树总长度 1+sqrt(3),是连接这 4 个村庄的最短公路网。
其中,为了让总长度更短,我们额外加进去的新点,就叫斯坦纳点。