查找删除断开连接图的所有节点对

时间:2018-06-04 11:15:27

标签: algorithm graph language-agnostic

给定无向连通图,找到所有节点对(由边连接),其删除会断开图形。
没有平行边缘,没有边缘将节点连接到自身。

问题看起来类似于找到连接的无向图的关节点(或桥) - 但是有一个扭曲,我们必须删除由边连接的一对顶点(以及连接到该对的所有其他边)

这是一个家庭作业问题。我一直试图解决它,阅读有关DFS和清晰度点算法(每个节点的书本深度和低点) - 但这些方法都没有帮助解决这个问题。我已经通过Cormen的算法简介进行了检查,但没有任何主题建议适当(授予,书籍有1500页)。

虽然找到关节点也会(大部分时间)找到这样的一对是真的,但是有很多对不是关节点 - 考虑一个有4个顶点,5个边的图形(具有单个对角线的正方形):它有一个这样的对但没有关节点(也没有桥)。

我输了。帮助我,堆栈溢出,你是我唯一的希望。

3 个答案:

答案 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以获取有关算法的更多信息。简而言之:

  1. 为V
  2. 中的某个根节点r计算DFS树T.
  3. r是一个发音点,如果它在T
  4. 中有多个孩子
  5. V中的任何其他节点v是关节点,如果它在T中具有满足以下条件的子v':在以V'为根的T的子树T'中没有节点具有到祖先的后端v
  6. 让图G上的DFS结果为V中节点v上的函数c.c(v)是N_v的子集,如果满足以下两个条件,它在c(v)中保持v' :

    1. v'是T
    2. 中v的孩子
    3. 根据v'的子树T'中没有任何节点具有v的祖先的后边缘
    4. 注意,对于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个切割。