京都大学 情報学研究科 数理工学専攻 2023年8月実施 グラフ理論
Author
祭音Myyura
Description
日本語版
G=(V,E) を節点集合 V、 枝集合 E から成る単純強連結有向グラフとし、V に属する節点の個数を n、Eに属する枝の本数を m とする。
G の各枝 e∈E に実数値重み w(e) を与えて得られるネッタワークを N=[G,w] とする。
節点 u から節点 v への有向枝は (u,v) と書き、その枝重みは w(u,v) とも書く。
節点 v1,v2,…,vk をこの順に訪ねる路 P=(v1,v2,…,vk) について、枝の本数を μ(P)≜k−1、枝重みの和を ω(P)≜∑i=1k−1w(vi,vi+1) と書く。
節点 s∈V が与えられたものとする。各節点 v∈V について、s から v への路 P で μ(P)≤n−1 を満たすものにおける ω(P) のうち、最小値を d(v) と定める。
また s から v への単純路 S における ω(S) のうち、最小値を d∗(v) と定める。
ω(C)<0 を満たす閉路 C を負閉路と呼ぶ。以下の問いに答えよ。
(i) N に負閉路が存在しないとき、かつその時に限り、
d(u)+w(u,v)≥d(v), ∀(u,v)∈E
が成り立つことを示せ。
(ii) N に負閉路が存在するかどうかを判定し、もし存在しない場合には全ての v∈V に対して d∗(v) を出力する、O(mn) 時間のアルゴリズムを与えよ。
English Version
Let G=(V,E) denote a simple, strongly connected digraph with a vertex set V and an edge set E, let n denote the number of vertices in V, and let m denote the number of
edges in E.
Let N=[G,w] denote a network obtained from G by assigning a real value w(e) to each edge e∈E as its weight.
A directed edge from a vertex u to a vertex v is denoted by (u,v) and its weight is written as w(u,v).
When a path P=(v1,v2,…,vk) visits vertices v1,v2,…,vk in this order, let μ(P)≜k−1 denote the number of edges in P and let ω(P)≜∑i=1k−1w(vi,vi+1) denote the summation of weights of edges in P
Suppose that a vertex s∈V is given. For each vertex v∈V, we define d(v) to be the minimum of ω(P) among all paths P from s to v such that μ(P)≤n−1.
We define d∗(v) to be the minimum of ω(S) among all simple paths S from s to v.
A cycle C is called a negative cycle if ω(C)<0.
Answer the following questions.
(i) Prove that there is no negative cycle in N if and only if
d(u)+w(u,v)≥d(v), ∀(u,v)∈E
(ii) Show an O(mn)-time algorithm that determines whether or not there exists a negative cycle in N and that outputs d∗(v) for all v∈V if no negative cycle exists.
题目描述
设 G=(V,E) 为简单强连通有向图,∣V∣=n、∣E∣=m。网络 N=[G,w] 给每条边 e 赋实权 w(e)。对依次经过
v1,…,vk 的有向路 P=(v1,…,vk),定义
μ(P)=k−1,ω(P)=i=1∑k−1w(vi,vi+1).
给定 s∈V。对每个 v∈V,令 d(v) 为所有从 s 到 v 且边数不超过 n−1 的路的最小权重和;令 d∗(v) 为从 s 到 v 的所有简单路的最小权重和。若回路 C 满足 ω(C)<0,称其为负环。回答:
- 证明 N 不含负环,当且仅当
d(u)+w(u,v)≥d(v),∀(u,v)∈E.
- 给出一个 O(mn) 时间算法:判定 N 是否存在负环;若不存在,则输出所有 v∈V 的 d∗(v)。
Kai
(i)
(a) ⇒ (If there is no negative cycle, then d(u)+w(u,v)≥d(v),∀(u,v)∈E)
Prove by contradiction:
Assume that there exists an edge (u′,v′)∈E such that d(u′)+w(u′,v′)<d(v′).
Let Pu′=(s,u1,u2,…,u′) denote a path from s to u′ of weights ω(Pu′)=d(u′) and Pv′=(s,v1,v2,…,v′) denote a path from s to v′ of weights ω(Pv′)=d(v′).
Let Pu′v′=(s,u1,u2,…,u′,v′).
Since d(v′)>d(u′)+w(u′,v′), by the definition of d(v′) we know that μ(Pu′v′)>n−1, i.e., Pu′v′ is not a simple path.
W.l.o.g we assume that Pu′v′=(s,u1,u2,…,uk,uk+1,…,uk+i,uk,…,u′,v′) only contains 1 sub-cycle C′=(uk,uk+1,…,uk+i,uk).
Assume that ω(C′)≥0, let Pv′′=(s,u1,u2,…,uk,…,u′,v′) denote the path obtained by remove the sub-cycle C′ of Pu′v′, we have
ω(Pv′′)=ω(Pu′v′)−ω(C′)=d(u′)+w(u′,v′)−ω(C′)<d(v′)−ω(C′)
and μ(Pv′′)≤n−1, which is contradictory to the definition of d(v′).
Hence ω(C′)<0, which is contradictory to the condition "there is no negative cycle".
Therefore, if there is no negative cycle, then d(u)+w(u,v)≥d(v),∀(u,v)∈E.
(b) ⇐ (If d(u)+w(u,v)≥d(v),∀(u,v)∈E, then there is no negative cycle)
Prove by contradiction:
Assume that there exists a negative cycle
C′=(u1,u2,…,uk,uk+1=u1), ω(C′)<0.
From the condition we know that ∀(ui,ui+1)∈C′,d(ui)+w(ui,ui+1)≥d(ui+1),
Hence
d(u1)+w(u1,u2)d(u2)+w(u2,u3)⋯d(uk)+w(uk,u1)≥d(u2)≥d(u3)≥d(u1)
sum over all the equations,
w(u1,u2)+w(u2,u3)+⋯+w(uk,u1)≥0
which is contradictory to the fact that
ω(C′)=w(u1,u2)+w(u2,u3)+⋯+w(uk,u1)<0.
Therefore, if d(u)+w(u,v)≥d(v),∀(u,v)∈E, then there is no negative cycle.
(ii)
Bellman-Ford algorithm (Wiki)
function BellmanFord(list vertices, list edges, vertex source) is
// This implementation takes in a graph, represented as
// lists of vertices (represented as integers [0..n-1]) and edges,
// and fills two arrays (distance and predecessor) holding
// the shortest path from the source to each vertex
distance := list of size n
predecessor := list of size n
// Step 1: initialize graph
for each vertex v in vertices do
// Initialize the distance to all vertices to infinity
distance[v] := inf
// And having a null predecessor
predecessor[v] := null
// The distance from the source to itself is, of course, zero
distance[source] := 0
// Step 2: relax edges repeatedly
repeat |V|−1 times:
for each edge (u, v) with weight w in edges do
if distance[u] + w < distance[v] then
distance[v] := distance[u] + w
predecessor[v] := u
// Step 3: check for negative-weight cycles
for each edge (u, v) with weight w in edges do
if distance[u] + w < distance[v] then
predecessor[v] := u
// A negative cycle exists; find a vertex on the cycle
visited := list of size n initialized with false
visited[v] := true
while not visited[u] do
visited[u] := true
u := predecessor[u]
// u is a vertex in a negative cycle, find the cycle itself
ncycle := [u]
v := predecessor[u]
while v != u do
ncycle := concatenate([v], ncycle)
v := predecessor[v]
error "Graph contains a negative-weight cycle", ncycle
return distance, predecessor