算法设计与分析-习题9.2

目录

[1.应用 Kruskal 算法求下列图的最小生成树。](#1.应用 Kruskal 算法求下列图的最小生成树。)

2.判断正误:

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

数学归纳法

  1. 初始:每个点自己是一棵树h=0,s=1,1 ≥ 2⁰=1 ✔ 成立。

  2. 假设:两棵树满足s₁ ≥ 2ʰ¹,s₂ ≥ 2ʰ²。

  3. 合并(按大小,小的挂大的):不妨设 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 个村庄的最短公路网。

其中,为了让总长度更短,我们额外加进去的新点,就叫斯坦纳点。

相关推荐
仟濹1 小时前
【算法打卡day26(2026-03-18 周三)今日算法:「回溯算法」& 蓝桥杯真题(简单题型)】7个
算法·蓝桥杯
Book思议-2 小时前
【数据结构实战】:基于C语言单链表实现红旗渠景区年卡信息管理系统
c语言·开发语言·数据结构
C蔡博士2 小时前
计算复杂性:P、NP、NP-hard、NP-complete 一篇通关
算法·计算理论·np问题·计算复杂性
add45a2 小时前
C++与自动驾驶系统
开发语言·c++·算法
TsukasaNZ2 小时前
C++中的命令模式
开发语言·c++·算法
superkcl20222 小时前
指针常量有什么用呢?
开发语言·c++·算法
华清远见成都中心2 小时前
嵌入式春招笔试高频算法题(附解题思路)
算法
像污秽一样2 小时前
算法设计与分析-习题9.1
数据结构·算法·dfs·dp·贪婪
無限進步D2 小时前
差分算法 cpp
c++·算法·蓝桥杯·竞赛