【问题标题】:Find connected components in a graph [closed]在图中查找连接的组件[关闭]
【发布时间】:2014-01-31 10:34:37
【问题描述】:

如果我有一个无向图(实现为顶点列表),我如何找到它的连通分量?如何使用快速联合?

【问题讨论】:

  • 顶点表示为一个列表,但是边是如何表示的呢?
  • 图 G 是一个整数列表。如果 j 在列表 G[i] 上且 i 在 G[j] 上,则存在 i 到 j 的边形式。
  • 这个问题似乎是题外话,因为它是关于计算机科学,而不是编程,属于cs.stackexchange.com
  • @user52045 我已经回答了这个问题,因为您似乎对 SO 很陌生,但现在您也应该发布您尝试过的内容。
  • 这个问题怎么太宽泛了?

标签: algorithm graph


【解决方案1】:

使用深度优先搜索 (DFS) 将所有单独的连接组件标记为已访问:

dfs(node u)
  for each node v connected to u :
    if v is not visited :
      visited[v] = true
      dfs(v)


for each node u:
  if u is not visited :
    visited[u] = true
    connected_component += 1
    dfs(u)

最好的方法是使用这种简单的方法,即线性时间 O(n)。
既然您询问了联合查找算法:

for each node parent[node] = node  

for each node u :
   for each node v connected to u :  
       if findset(u)!=findset(v) :
           union(u,v)  

**I assume you know about how findset and union works **  
for each node if (parent[node] == node)  
    connected_component += 1

【讨论】:

  • 有什么理由使用 dfs 而不是 bfs?
  • @Will :是的,因为 BFS 覆盖了从您最初选择的节点 X 开始的“层”中的图形,这意味着如果无法从 X 访问某个节点 Y,然后 BFS 不会访问它。虽然这种情况下的 DFS 可以,但为什么呢?因为当你覆盖了来自X 的所有可达节点并且仍然有一些未访问的节点时,DFS 将从这些节点之一重新开始,因此 DFS 为你提供了一个森林,而 BFS 为你提供了一棵树。
  • @ThunderWiring 我不确定我是否理解。是什么阻止我们从那些未访问/未发现的节点之一运行 BFS? DFS 的定义中似乎没有任何内容需要为图中的每个未发现节点运行它。如果您在每个未发现的节点上运行 BFS 或 DFS,您将获得连接组件的森林。
  • @ThunderWiring 至于你声称 Aseem 的算法不正确:你不需要一个明确的基本情况(你称之为“停止条件”)来退出递归,因为 for 循环(上面的第 2 行)最终将终止(因为给定的节点有有限的多个节点连接到它)。一旦所有未访问的邻居都被dfs'd,顶级dfs 调用将全部触底。
  • @ThunderWiring 我不同意你的说法“如果某个节点 Y 无法从 X 访问,那么 BFS 将不会访问它。而 DFS 在这种情况下会这样做......”如果一个节点无法从 X 到达,如果您从 X 开始,则 BFS 或 DFS 都无法为您提供该节点。您能举个例子说明您所说的吗?
【解决方案2】:

对于每个edge(u,v) 使用快速联合查找数据结构查找union(u,v) 并使用find(v) 查找每个顶点的集合。每个新集合都是图中的一个连通分量

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2014-07-10
    • 1970-01-01
    相关资源
    最近更新 更多