Kosaraju 算法

Posted by sjj118 on 2017-02-01

算法介绍:

Kosaraju 算法是一个求强连通分量的算法。因为某道题要压位求强连通分量所以学习了一下这个算法,不过听说 tarjan 也能压位,然而我没有看懂。。

算法流程:

  1. 对原图进行 dfs ,记录 dfn 为每个节点的离开时间
  2. 按照 dfn 从大到小的顺序对反图进行 dfs ,能够遍历到的节点作为一个强连通分量。

算法证明:

充分性:

若两个点 a 和 b 在同一个强连通分量内,则步骤2时一定能从 dfn 较大的点走到 dfn 较小的点。

必要性:

两个点 a 和 b 在同一个强连通分量的充要条件是:能从 a 走到 b 且能从 b 走到 a 。能从 b 走到 a 等价于能在反图中从 a 走到 b 。在反图中 dfs ,首先保证了第二个条件,只要证明在原图中能从 a 走到 b 就行了。

假设在原图中遍历到点 b 时没有遍历过点 a ,那么由于 b 能走到 a ,所以 a 的 dfn 一定小于 b 的 dfn ,所以一定先遍历点 a 再遍历点 b 。如果经过点 a 和 点 b 时不在同一次遍历中,则 a 的 dfn 一定小于 b 的 dfn ,所以一定是先经过 a ,然后走到 b ,即 a 能走到 b 。

时间复杂度:

直接运行是 \(O(n+m)\) 的,如果是稠密图可以压位做到 \(O(\frac{n^2}{32})\)