在Kosaraju算法中,我遇到了两种可能的实现方式:
1)在原始图中按顶点的拓扑顺序在反向图中搜索强连通的分量。
2)按照反向图中顶点的拓扑顺序,在原始图中搜索强连通的分量。
我想要的是使用颠倒的拓扑顺序的顶点在原始图中搜索强连通的组件是错误的。在内存方面也将更好,因为不需要新的邻接表。
资料来源:1)E-Maxx,2)CLRS书
答案 0 :(得分:2)
术语问题:
您正在谈论拓扑顺序,但是当且仅当图形为DAG(有向无环)时,拓扑顺序才存在。如果只想使用DAG,则每个顶点都是其自身的组成部分,因此您已经具有SCC(牢固连接的组件)。如果要在有向图上找到SCC,则需要将拓扑顺序更改为 DFS完成时间。 CLRS本书仅提及完成时间f[u]
:
- 调用DFS(G ^ T),但在DFS的主循环中,按f [u] ...递减的顺序考虑顶点。
您的问题的重构:
在原始图形中以顶点
f[u]
的顺序搜索考虑顶点的强连通组件是否错误?
答案:
是的,这是错误的。
反例:考虑下图:
,其中包含两个成分C
和C'
。如果您运行的是第一个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)。 如果我们谈论蛮力方法来解决这个问题,我们可以按照以下步骤进行:
如果我们谈论这种方法的复杂性,它将需要三次时间,即 O(v^3)。因此,我们可以使用 Kosaraju 算法 优化这种方法,该算法可以在 O(n+m) 时间内运行我们的算法。使用Kosaraju算法解决强连通分量问题的步骤是:
每个成功的 DFS 将有五个 1-SCC 强连通分量。这就是 Kosaraju 算法 在 O(n+m) 时间内的工作原理其中n 是图中的节点数,m 是边数。