Tarjan强连通分量算法

本文介绍了Tarjan算法在求解有向图强连通分量(SCC)中的应用。通过DFS生成树的概念,解释了如何利用反祖边找到SCC,并给出了具体的实现步骤。文章还提供了例题和代码,帮助理解算法的运用。
摘要由CSDN通过智能技术生成

前言

“Tarjan 陪伴强连通分量
生成树完成后思路才闪光
欧拉跑过的七桥古塘
让你 心驰神往”
——《膜你抄》

引入

什么是强联通分量(SCC)呢?

有向图强连通分量:在有向图 G G G 中,如果两个顶点 v i , v j v_i,v_j vi,vj 间( v i > v j v_i>v_j vi>vj)有一条从 v i v_i vi v j v_j vj 的有向路径,同时还有一条从 v j v_j vj v i v_i vi 的有向路径,则称两个顶点强连通(strongly connected)。如果有向图 G G G 的每两个顶点都强连通,称 G G G 是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。

看下面这个有向图:

请添加图片描述
它有 3 3 3 个强联通分量,如图:
请添加图片描述
显然,任何一个强连通分量之中的所有点之间均可到达。

那我们怎么求出一个图中的强连通分量呢?

直接DFS?显然会超时。

对于这个问题,美国计算机科学家Robert Tarjan(罗伯特·塔扬)提出了著名的Tarjan算法。

【题外话】

CSP之前膜拜大佬增加RP:

Robert Tarjan

Tarjan算法

首先,我们应该了解一下DFS生成树,即按照DFS次序形成的树。

以下选自OI Wiki


请添加图片描述
有向图的 DFS 生成树主要有 4 种边(不一定全部出现):

  1. 树边(tree edge):示意图中以黑色边表示,每次搜索找到一个还没有访问过的结点的时候就形成了一条树边。
  2. 反祖边(back edge):示意图中以红色边表示(即 7 → 1 7\rightarrow1 71),也被叫做回边,即指向祖先结点的边。
  3. 横叉边(cross edge):示意图中以蓝色边表示(即 9 → 7 9\rightarrow7 97),它主要是在搜索的时候遇到了一个已经访问过的结点,但是这个结点 并不是 当前结点的祖先时形成的。
  4. 前向边(forward edge):示意图中以绿色边表示(即 3 → 6 3\rightarrow6 36),它是在搜索的时候遇到子树中的结点的时候形成的。

以上选自OI Wiki

对于文章开头的那张图,我们尝试对它进行DFS,组成DFS树:
请添加图片描述

我们发现,那条反祖边(红边)指向了DFS树的根,形成了一个环,环是强连通的。

但是,我们怎么知道这个环是不是强联通分量呢?

很显然,我们只需要找到一条终点是DFS树的根,起点尽量靠下的反祖边,这条反祖边形成的一定是SCC。

注意,这里说的DFS树不一定是整个图的DFS树,也可以是子图的DFS树。

然而,我们又怎么确定哪些点是在SCC中呢?

如果结点 u u u 是某个强连通分量在搜索树中遇到的第一个结点,那么这个强连通分量的其余结点肯定是在搜索树中以 u u u 为根的子树中。 ——OI Wiki

为什么呢?

即得易见平凡,仿照上例显然,留作习题答案略,读者自证不难。反之亦然同理,推论自然成立,略去过程QED ,由上可知证毕。
——《西江月·证明》

我们假设一个点 x x x 在SCC中却不在以 u u u 为根的子树中,那么从 u u u x x x 的过程中一定有一个反祖边或横叉边使其在子树外,而根据定义,这两种边都在 u u u 之前被搜索到,与“结点 u u u 是某个强连通分量在搜索树中遇到的第一个结点”矛盾,得证。

我们只需要开一个栈,从树根开始,把遍历到的点都加到栈里。当我们发现一个SCC存在时,就不断地弹出栈,直到弹出DFS树的树根为止。这样,弹出的节点就是SCC中的节点。

那么,算法的基本原理已经了解了,我们来具体地实现一下。

首先,我们要记录每个节点是第几个被搜索到的(即时间戳),记作

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值