跳到主要内容

東京大学 情報理工学系研究科 コンピュータ科学専攻 2016年8月実施 専門科目I 問題2

Author

祭音Myyura (co-authored with GPT 5.6 SOL)

Description

Suppose that we are given an undirected graph GG where each edge is associated with a cost. A minimum spanning tree is a subgraph of the graph such that: it connects all the vertices; it is a tree; and it takes a minimum total cost. The following pseudo code (Algorithm A) shows an algorithm to compute a minimum spanning tree. We let the numbers of vertices and edges of GG be denoted by VV and EE, respectively.

Step 1. Choose an arbitrary vertex and let GG' be the subtree of GG consisting of only that vertex.

Step 2. Choose an edge with a minimum cost, out of (a)\boxed{(a)}, and add the edge and its end vertices to GG'.

Step 3. Repeat Step 2 until GG' contains all the vertices of GG.

Answer the following question.

(1) Answer an appropriate phrase that fills (a)\boxed{(a)} above.

There are multiple ways to implement Algorithm A. Specifically, computation time differs depending on how to find an edge with a minimum cost in Step 2.

Answer the following questions.

(2) Suppose that GG is dense (V2EV^2\approx E) and given as an adjacency matrix. Explain a time-efficient implementation of Algorithm A in this case.

Answer also the time complexity of the implementation, and explain why.

(3) Suppose that GG is sparse (VEV\approx E) and given as adjacency lists. Explain a time-efficient implementation of Algorithm A in this case.

Answer also the time complexity of the implementation, and explain why.

(4) Show that the graph GG' obtained using Algorithm A is a minimum spanning tree of the graph GG.

题目描述

给定带权连通无向图 GG。最小生成树是连接全部顶点、无环且总权值最小的子图。记顶点数、边数分别为 V,EV,E。算法 A 如下:

  1. 任取一个顶点,以该点为唯一顶点的子树记为 GG'
  2. 从空格(a)所指定的边中选择权值最小者,将该边及其端点加入 GG'
  3. 重复步骤 2,直至 GG' 包含 GG 的全部顶点。

(1)填写(a)。

(2)若 GG 为稠密图(V2EV^2\approx E),且以邻接矩阵给出,说明算法 A 的高效实现及其时间复杂度,并说明理由。

(3)若 GG 为稀疏图(VEV\approx E),且以邻接表给出,回答同一问题。

(4)证明算法 A 得到的 GG'GG 的最小生成树。

Kai

以下假设 GG 连通。若 GG 不连通,则不存在覆盖全部顶点的生成树,算法会在跨割边集合为空时停止。

(1)

(a)应填:恰有一个端点属于当前 GG' 的边,即割

(V(G),V(G)V(G))\bigl(V(G'),\,V(G)\setminus V(G')\bigr)

上的边。这就是 Prim 算法。

(2)

对每个尚未加入 GG' 的顶点 vv,维护

d[v]=min{c(u,v)uV(G)}d[v]=\min\{c(u,v)\mid u\in V(G')\}

及取得该最小值的父顶点。每轮线性扫描所有未选顶点,取 d[v]d[v] 最小者加入;再扫描邻接矩阵中 vv 所在的一行以更新各 dd。每轮耗时 O(V)O(V),共 V1V-1 轮,故时间为 O(V2)O(V^2),额外空间为 O(V)O(V)

(3)

仍维护 d[v]d[v],但用以 dd 为键的最小堆保存未选顶点。取最小值后,只沿新顶点的邻接表检查相邻边,并执行减键操作。二叉堆实现的时间为

O((V+E)logV)=O(ElogV),O((V+E)\log V)=O(E\log V),

空间为 O(V+E)O(V+E)。在 EVE\approx V 时优于邻接矩阵实现。

(4)

归纳证明:算法每轮后,都存在一棵包含当前 GG' 的最小生成树 TT。初始时结论显然成立。

设本轮选择跨割的最轻边 ee。若 eTe\in T,结论不变。若 eTe\notin T,把 ee 加入 TT 会形成唯一环;环上从割的一侧走到另一侧时必经过另一条跨割边 ff。由 ee 的选择,c(e)c(f)c(e)\le c(f)。于是

T=Tf+eT'=T-f+e

仍是生成树,且总权值不大于 TT,所以也是最小生成树,并包含扩张后的 GG'。归纳成立。算法结束时 GG' 本身含 V1V-1 条边并覆盖全部顶点,故 G=TG'=T,即为最小生成树。