Обновление до моего предыдущего ответа, основанное на предложении @MkjG использовать DFS для вычисления точек сочленения.
Пусть граф будет G = (V, E) с V: = {v_1, ..., v_n} _.Для каждого подмножества V 'из V пусть G_V' будет подграфом, индуцированным узлами, содержащим узлы V \ V '.Для связного G мы называем v в V точкой сочленения, если G_ {v} не является связным.Пусть N_v будет множеством соседей v в G.
Точки сочленения можно вычислить с помощью DFS, прочитайте здесь для получения дополнительной информации об алгоритме.Вкратце:
- вычисляет дерево DFS T для некоторого корневого узла r в V
- r - это точка сочленения, если в T
Пусть результатом DFS на графе G будет функция c на узлах v в V. c (v) является подмножеством N_v, оно содержит v 'в c (v), если обавыполняются следующие условия:
- v 'является потомком v в T
- ни один узел в поддереве T' корня T в корне v не имеет заднего края по отношению к предкуиз v
Обратите внимание, что для корневого узла r в T c (r) - это множество всех дочерних элементов r.Функция c может быть вычислена за время O (n + m).
Вычислить пары разделителей следующим образом:
# performs DFS on G for some root node r
c = DFS(G,r)
# computes articulation points of G and corresponding number of components
aps = {}
compCounts = {}
for each v in V:
numComps = |c(v)|
if v != r:
++numComps
if numComps > 1:
add v to aps
compCounts[v] = numComps
# computes the set of all separator pairs containing at least on ap
S = {}
for each v in aps:
numComps = compCounts[v]
for each v' in N_v:
if numComps > 2:
# G_{v,v'} has at least two connected components
add {v,v'} to S
else:
# if v' is an isolated node in G_{v}, then G_{v,v'} is connected
if N_v' != {v}:
add {v,v'} to S
# computes remaining separator pairs
for each v in V \ aps:
compute G_{v}
# performs DFS on G_{v} for some root r_v != v
c_v = DFS(G_{v},r_v)
# adds separator pairs for articulation points of G_{v} in N_v
for each v' in N_v:
numComps = |c(v')|
if v' != r_v:
++numComps
if numComps > 1:
add{v,v'} to S
Время выполнения в O (n * (n + m))