関節点(articulation points), 切断点 (cut vertices)
概要
無向グラフ \(G = (V, E)\) における関節点(除去するとグラフが連結でなくなる頂点)を検出する。
DFSでlowlinkを計算しながら関節点を求める。
計算量
\(O(|V| + |E|)\)
実装
# 関節点(Articulation Points)
def get_articulation_points(G, N, start=0):
order = [None]*N
result = []; count = 0
def dfs(v, prev):
nonlocal count
r_min = order[v] = count # 到達時にラベル
fcnt = 0; p_art = 0
count += 1
for w in G[v]:
if w == prev:
continue
if order[w] is None:
ret = dfs(w, v)
# 子の頂点が到達できたのが、自身のラベル以上の頂点のみ
# => 頂点vは関節点
p_art |= (order[v] <= ret)
r_min = min(r_min, ret)
fcnt += 1
else:
r_min = min(r_min, order[w])
p_art |= (r_min == order[v] and len(G[v]) > 1)
if (prev == -1 and fcnt > 1) or (prev != -1 and p_art):
# 頂点startの場合は、二箇所以上の子頂点を調べたら自身は関節点
result.append(v)
return r_min
dfs(start, -1)
return result