跳到主要内容

京都大学 情報学研究科 数理工学専攻 2019年8月実施 アルゴリズム基礎

Author

祭音Myyura

Description

日本語版

G=(V,E)G=(V,E) を節点集合 VV,枝集合 EE から成る連結な単純無向グラフとし,GG は隣接リストにより貯えられているとする. 二点 u,vVu, v \in V 間の路の最短の長さを dist(u,v)\text{dist}(u,v) と記す. 以下の問いに答えよ.

(1) 任意の点 sVs \in V を選ぶ.dist(s,u)=dist(s,v)\text{dist}(s, u) = \text{dist}(s, v) を満たす枝 uvEuv \in E が存在すれば,枝 uvuv は長さ奇数の単純閉路に含まれることを証明せよ.

(2) GG が二部グラフであるかどうかを O(V+E)O(|V| + |E|) 時間で判定する方法を示せ.

(3) 異なる二点 s,tVs, t \in V に対して,s,ts, t 間の最短路が唯一であるかどうかを O(V+E)O(|V| + |E|) 時間で判定する方法を示せ.

English Version

Let G=(V,E)G=(V,E) denote a simple connected undirected graph with a vertex set VV and an edge set EE. Assume that GG is stored in adjacency lists. For two vertices u,vVu, v \in V, let dist(u,v)\text{dist}(u,v) denote the shortest length of a path between them. Answer the following questions.

(1) Let sVs \in V be an arbitrary vertex. Prove that if there is an edge uvEuv \in E such that dist(s,u)=dist(s,v)\text{dist}(s, u) = \text{dist}(s, v) then edge uvuv is contained in a simple cycle of an odd length.

(2) Show how to test whether GG is a bipartite graph or not in O(V+E)O(|V| + |E|) time.

(3) Let s,tVs, t \in V be two distinct vertices. Show how to test whether GG has only one shortest path between ss and tt or not in O(V+E)O(|V| + |E|).

Kai

Let P|P| denote the length of a path PP.

(1)

Let PuP_u be a shortest path from ss to uu, and let PvP_v be a shortest path from ss to vv.

Since both paths start at ss, they have at least one common vertex. Let zz be the last common vertex of PuP_u and PvP_v.

Denote by Pu[z,u]P_u[z,u] the subpath of PuP_u from zz to uu, and by Pv[z,v]P_v[z,v] the subpath of PvP_v from zz to vv. Since zz is the last common vertex of PuP_u and PvP_v, these two subpaths have no common vertices except zz.

Let

u=Pu[z,u],v=Pv[z,v].\ell_u = |P_u[z,u]|,\qquad \ell_v = |P_v[z,v]|.

We show that u=v\ell_u=\ell_v.

Since PuP_u and PvP_v are shortest paths, by assumption,

Pu=d(s,u)=Pv=d(s,v).|P_u|=d(s,u)=|P_v|=d(s,v).

Also,

Pu=Pu[s,z]+u,|P_u|=|P_u[s,z]|+\ell_u,

and

Pv=Pv[s,z]+v.|P_v|=|P_v[s,z]|+\ell_v.

Since every subpath of a shortest path is also a shortest path, both Pu[s,z]P_u[s,z] and Pv[s,z]P_v[s,z] are shortest paths from ss to zz. Therefore,

Pu[s,z]=Pv[s,z]=d(s,z).|P_u[s,z]|=|P_v[s,z]|=d(s,z).

Combining these equalities, we obtain

u=v.\ell_u=\ell_v.

Now consider the cycle formed by the path Pu[z,u]P_u[z,u], the edge (u,v)(u,v), and the reverse of the path Pv[z,v]P_v[z,v].

Because zz is the last common vertex of PuP_u and PvP_v, the two paths Pu[z,u]P_u[z,u] and Pv[z,v]P_v[z,v] have no common vertices except zz. Therefore, the above closed walk is a simple cycle.

The length of this cycle is

u+1+v.\ell_u+1+\ell_v.

Since u=v\ell_u=\ell_v, this length is

2u+1,2\ell_u+1,

which is odd.

(2)

The algorithm can be established from the following statement and (1):

  • A simple undirected graph G=(V,E)G=(V,E) is bipartite iff it contains no odd length cycle.

(\Rightarrow) When GG is bipartite, let X1,X2VX_1, X_2 \subseteq V denote the partition of GG.

Assume that there exists a cycle C=(u1,u2,,u2k+1,u2k+2=u1)C = (u_1, u_2, \ldots, u_{2k+1}, u_{2k+2}=u_1) in GG of odd length.

W.l.o.g we assume that u1X1u_1 \in X_1. Then we know that vertices u2i,(i=1,2,)u_{2i}, (i=1,2, \ldots) are in vertex set X2X_2, which implies that vertex u2k+2=u1u_{2k+2}=u_1 is in vertex set X2X_2, a contradiction.

Therefore, if GG is bipartite, there is no odd length cycle in GG.

(\Leftarrow) Run BFS from arbitrary ss. Color each vertex according to the parity of dist(s,v)\text{dist}(s,v).

For every edge uvuv, if uu and vv have the same color, then since adjacent vertices in an unweighted graph have BFS distances differing by at most 11, they must satisfy dist(s,u)=dist(s,v)\text{dist}(s,u)=\text{dist}(s,v).

By (1), this edge lies on an odd cycle, so G is not bipartite. If no such edge exists, all edges go between the two color classes, hence the graph is bipartite.

Algorithm

Let sVs \in V be an arbitrary vertex. We use BFS to color vertices according to the parity of their distances from ss, and then check whether there exists an edge whose endpoints have the same color.

algorithm IsBipartite(G):
for each v in V:
color[v] <- null

choose an arbitrary vertex s
color[s] <- RED
Q <- create an empty queue
Q.enqueue(s)

while Q is not empty:
n1 <- Q.dequeue()
for each n2 in n1.Adj():
if color[n2] = null:
if color[n1] = RED:
color[n2] <- BLUE
else:
color[n2] <- RED
Q.enqueue(n2)
else:
if color[n2] = color[n1]:
return "Graph is not bipartite"

return "Graph is bipartite"

Since BFS scans each vertex and each edge a constant number of times, the running time is O(V+E)O(|V|+|E|).

(3)

Let dist[v]\text{dist}[v] be the distance from ss to vv, and let cnt[v]\text{cnt}[v] denote the number of shortest paths from ss to vv, truncated at 22. Thus, cnt[v]=2\text{cnt}[v]=2 means that there are at least two shortest paths from ss to vv.

for each v in V:
dist[v] = INF
cnt[v] = 0

dist[s] = 0
cnt[s] = 1
Q.push(s)

while Q is not empty:
u = Q.pop()
for each v in Adj[u]:
if dist[v] == INF:
dist[v] = dist[u] + 1
cnt[v] = cnt[u]
Q.push(v)
else if dist[v] == dist[u] + 1:
cnt[v] = min(2, cnt[v] + cnt[u])

if cnt[t] == 1:
return "unique"
else:
return "not unique"