紧密连接的组件:Kosaraju算法

时间:2018-11-02 05:16:48

标签: graph-theory depth-first-search strongly-connected-graph

在Kosaraju算法中,我遇到了两种可能的实现方式:

1)在原始图中按顶点的拓扑顺序在反向图中搜索强连通的分量。

2)按照反向图中顶点的拓扑顺序,在原始图中搜索强连通的分量。

我想要的是使用颠倒的拓扑顺序的顶点在原始图中搜索强连通的组件是错误的。在内存方面也将更好,因为不需要新的邻接表。

资料来源:1)E-Maxx,2)CLRS书

2 个答案:

答案 0 :(得分:2)

术语问题:

您正在谈论拓扑顺序,但是当且仅当图形为DAG(有向无环)时,拓扑顺序才存在。如果只想使用DAG,则每个顶点都是其自身的组成部分,因此您已经具有SCC(牢固连接的组件)。如果要在有向图上找到SCC,则需要将拓扑顺序更改为 DFS完成时间。 CLRS本书仅提及完成时间f[u]

  
      
  1. 调用DFS(G ^ T),但在DFS的主循环中,按f [u] ...递减的顺序考虑顶点。
  2.   

您的问题的重构:

  

在原始图形中以顶点f[u]的顺序搜索考虑顶点的强连通组件是否错误?

答案:

是的,这是错误的。

反例:考虑下图:

enter image description here

,其中包含两个成分CC'。如果您运行的是第一个DFS(从节点u开始),那么您将在结束时间之前以升序获得以下两个列表之一:

DFS列表1:{v,w',w,u}

DFS列表2:{w',v,w,u}

您真正要问的是,是否可以从原始图形的开头开始处理这些列表。如果选择第一个列表,则将通过从节点C'开始的DFS搜索提取分量v,然后通过从节点C开始的DFS搜索提取分量w'。但是,如果选择第二个列表并从原始图上的节点w'开始DFS,您将仅获得一个组件(整个图),这是错误的。

请注意,Kosaraju的算法在两种情况下均有效,因为它从列表末尾开始(两种情况下均为节点u),并通过对反向图进行DFS搜索来提取成分C。当我们到达列表中的节点C'时,将提取组件v

答案 1 :(得分:1)

Kosaraju 算法 是一种线性时间算法,用于寻找对有向图和无向图都适用的强连通分量。为方便起见,我们可以在图中表示,如果任何一组节点构成一个循环,则它是一个强连接组件(SCC)。 如果我们谈论蛮力方法来解决这个问题,我们可以按照以下步骤进行:

  1. 使用找到所有对的最短路径 Floyd Warshall 算法
  2. 检查任意两对之间的距离是否为无穷大,即无法到达,那么它不是SCC,否则它是SCC

如果我们谈论这种方法的复杂性,它将需要三次时间,即 O(v^3)。因此,我们可以使用 Kosaraju 算法 优化这种方法,该算法可以在 O(n+m) 时间内运行我们的算法。使用Kosaraju算法解决强连通分量问题的步骤是:

  1. 对图执行深度优先搜索(DFS)并将节点推入堆栈。
  2. 通过反转图的边来找到图的转置。
  3. 将节点一个一个地从堆栈中弹出,然后再次对修改后的图执行DFS

每个成功的 DFS 将有五个 1-SCC 强连通分量。这就是 Kosaraju 算法O(n+m) 时间内的工作原理其中n 是图中的节点数,m 是边数。