Kosaraju 算法

求有向图强连通分量的一种算法。

算法步骤:

  1. 用 dfs 遍历整个有向图,取出它的后序遍历(可能是多次dfs,但并不影响,可以直接拼起来)。
  2. 建反图(原图的每条边反向),按照后序从后往前,以它为起点遍历反图。
  3. 遍历反图时,所有能够到达的,未经过的点(一定是序列中在它之前出现的)都和起点在一个强连通分量当中。

为什么正确?对反图 $u$ 能到达 $v$ 的两个点 $u,v$(序列中 $v$ 在 $u$ 之前出现)进行讨论。反图 $u$ 能到达 $v$ 也就是原图 $v$ 能到达 $u$。

  1. 如果原图 $u$ 也能到达 $v$(祖先关系),符合强连通的定义,在一个强连通分量里。
  2. 如果原图 $u$ 不能到达 $v$(非祖先关系),现在说明原图 $v$ 能到达 $u$,因为是后序,所以 $v$ 在 $u$ 之前且 $u$ 不能到 $v$ 说明 $v$ 已经遍历完了,且 $v$ 不能到 $u$,矛盾。

上面说明了访问到的确是在一个SCC,它一定能遍历所有强连通分量吗?
考虑实际的每个强连通分量在 dfs 中第一个经过的点(不是一次 dfs 到的两个点一定不可能在同一个 SCC)。
因为它是 SCC 中第一个,SCC 的其它点没有被访问,所以它在访问顺序中最先,然后会正常访问到 SCC 中的所有点。

这个算法的好处是,你不需要知道每一条边,只需要能够快速找到当前点的一条对应点未访问过的出边即可。在某些边数很多,不能显式建图的题有用(如果是竞赛图还能把缩点后的链求出来,直接一遍排序即可)。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇