给定无向连通图,找到所有节点对(由边连接),其删除会断开图形。
没有平行边缘,没有边缘将节点连接到自身。
问题看起来类似于找到连接的无向图的关节点(或桥) - 但是有一个扭曲,我们必须删除由边连接的一对顶点(以及连接到该对的所有其他边)
这是一个家庭作业问题。我一直试图解决它,阅读有关DFS和清晰度点算法(每个节点的书本深度和低点) - 但这些方法都没有帮助解决这个问题。我已经通过Cormen的算法简介进行了检查,但没有任何主题建议适当(授予,书籍有1500页)。
虽然找到关节点也会(大部分时间)找到这样的一对是真的,但是有很多对不是关节点 - 考虑一个有4个顶点,5个边的图形(具有单个对角线的正方形):它有一个这样的对但没有关节点(也没有桥)。
我输了。帮助我,堆栈溢出,你是我唯一的希望。
答案 0 :(得分:1)
相当简单,也许不是最有效的:
让图形为G =(V,E),其中V:= {v_1,...,v_n}。对于V let G_V'的每个子集V',是包括节点V \ V'的节点诱导子图。进一步让N> _v_i:= {v_j in V:{v_i,v_j}在E和j>中。 i}是G中v_i的所有邻居的集合,索引大于i。最后,让c(G)成为图的连通分量集。
按如下方式计算对:
pairs = {}
for each v in V:
compute G_{v}
if G_{v} is unconnected:
for each v' in N>_v:
# Ensures that removal of v' does not render subgraph connected
# (Note comment by MkjG)
if |c(G_{v})| > 2 or {v'} not in c(G_{v}):
add {v,v'} to pairs
else:
for each v' in N>_v:
compute G_{v,v'}
if G_{v,v'} unconnected:
add {v,v'} to pairs
可以通过DFS或BFS在O(m + n)中检查连接性。因此运行时应为O(n * k *(m + n)),其中k是G的最大度数。
答案 1 :(得分:1)
根据@MkjG建议使用DFS计算清晰度点来更新我之前的答案。
让图形为G =(V,E),其中V:= {v_1,...,v_n} _。对于V let G_V'的每个子集V',是包括节点V \ V'的节点诱导子图。对于G连接,如果G_ {v}未连接,我们将V在V中称为关节点。设N_v为G中v的邻居集。
可以通过DFS计算关节点,阅读here以获取有关算法的更多信息。简而言之:
让图G上的DFS结果为V中节点v上的函数c.c(v)是N_v的子集,如果满足以下两个条件,它在c(v)中保持v' :
注意,对于T的根节点r,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))
答案 2 :(得分:0)
断开图形的一组k个边缘称为k-cut。您正试图枚举图表的所有2个切割。
This paper描述了一种有效的算法来枚举图的所有切割。应该可以对其进行调整以找到图表的所有2个切割。