跳到主要内容

京都大学 情報学研究科 数理工学専攻 2024年8月実施 グラフ理論

Author​

祭音Myyura

Description​

大学公表の原題 有限集合 AA に属する要素の個数を ∣A∣|A| と書く。 節点集合 VV および枝集合 EE からなる単純連結無向グラフ G=(V,E)G = (V, E) が与えられたものとする。 ただし ∣V∣≥3|V| \geq 3 とする。 始点 s∈Vs \in V を一つ選ぶ。 任意の節点 v∈Vv \in V に対し、ss から vv への最短路における枝の本数を dist(v)\text{dist}(v) と書き、ss から vv への最短路の総数を σ(v)\sigma(v) と書く。 また、dmax=max⁡v∈Vdist(v)d_{\text{max}} = \max_{v \in V} \text{dist}(v) とし、整数 i=0,1,…,dmaxi = 0, 1, \ldots, d_{\text{max}} に対して Vi={v∈V∣dist(v)=i}V_i = \{v \in V \mid \text{dist}(v) = i\} とする。以下の問いに答えよ。

(i) dmaxd_{\text{max}} および Vi,i=0,1,…,dmaxV_i, i = 0, 1, \ldots, d_{\text{max}} を、O(∣E∣)O(|E|) 時間で計算する方法を示せ。

(ii) すべての v∈Vv \in V に対して σ(v)\sigma(v) を O(∣E∣)O(|E|) 時間で計算する方法を示せ。

(iii) ある節点 t∈V∖{s}t \in V \setminus \{s\} と節点の部分集合 U⊆V∖{s,t}U \subseteq V \setminus \{s, t\} に対して、ss から tt への最短路のうち、UU に属する節点を少なくとも1個通過するものの個数を O(∣E∣)O(|E|) 時間で計算する方法を示せ。

(iv) ある節点 t∈V∖{s}t \in V \setminus \{s\}、節点の部分集合 U⊆V∖{s,t}U \subseteq V \setminus \{s, t\}、整数 1≤k≤∣U∣1 \leq k \leq |U| に対して、ss から tt への最短路のうち、UU に属する節点を少なくとも kk 個通過するものが存在するかどうかを、O(∣E∣)O(|E|) 時間で判定する方法を示せ。

题目描述​

对有限集合 AA,以 ∣A∣|A| 表示元素个数。给定简单连通无向图 G=(V,E)G=(V,E),且 ∣V∣≥3|V|\ge3,选定起点 s∈Vs\in V。对任意 v∈Vv\in V,令 dist⁡(v)\operatorname{dist}(v) 为从 ss 到 vv 的最短路边数,σ(v)\sigma(v) 为这类最短路的总条数,并定义

dmax⁡=max⁡v∈Vdist⁡(v),Vi={v∈V∣dist⁡(v)=i}(i=0,…,dmax⁡).d_{\max}=\max_{v\in V}\operatorname{dist}(v),\qquad V_i=\{v\in V\mid\operatorname{dist}(v)=i\} \quad(i=0,\ldots,d_{\max}).

回答:

  1. 给出在 O(∣E∣)O(|E|) 时间内计算 dmax⁡d_{\max} 及全部 ViV_i 的方法。
  2. 给出在 O(∣E∣)O(|E|) 时间内计算所有 σ(v)\sigma(v) 的方法。
  3. 对给定 t∈V∖{s}t\in V\setminus\{s\} 与 U⊆V∖{s,t}U\subseteq V\setminus\{s,t\},在 O(∣E∣)O(|E|) 时间内计算从 ss 到 tt 且至少经过一个 UU 中顶点的最短路条数。
  4. 对给定的上述 t,Ut,U 及整数 1≤k≤∣U∣1\le k\le|U|,在 O(∣E∣)O(|E|) 时间内判定是否存在从 ss 到 tt 且至少经过 kk 个 UU 中顶点的最短路。

Kai​

(i)​

dist[v] = -1
dist[s] = 0
V_0 = {s}
queue = [s]

while queue not empty:
u = pop_front(queue)
for v in N(u):
if dist[v] == -1:
dist[v] = dist[u] + 1
add v to V_{dist[v]}
push_back(queue, v)

d_max = max dist[v]

Since graph is connected, we have O(E)≥O(V)O(E) \geq O(V). Hence the time complexity is O(∣V∣+∣E∣)=O(∣E∣)O(|V| + |E|) = O(|E|).

(ii)​

sigma[v] = 0 for all v
sigma[s] = 1

for i = 0 to d_max - 1:
for u in V_i:
for v in N(u):
if dist[v] == dist[u] + 1:
sigma[v] += sigma[u]

(iii)​

a[v] = 0 for all v
a[s] = 1

for i = 0 to d_max - 1:
for u in V_i:
for v in N(u):
if dist[v] == dist[u] + 1 and v not in U:
a[v] += a[u]

return sigma[t] - a[t]

(iv)​

best[v] = -infinity for all v
best[s] = 0

for i = 0 to d_max - 1:
for u in V_i:
for v in N(u):
if dist[v] == dist[u] + 1:
gain = 1 if v in U else 0
best[v] = max(best[v], best[u] + gain)

return best[t] >= k