Tarjan 求有向图的强连通分量

Tarjan算法是一种用于寻找有向图强连通分量的深度优先搜索算法,由Robert E. Tarjan提出。算法基于深度优先遍历,通过维护一个栈来判断节点间是否构成强连通分量。在遍历过程中,通过追溯值(low值)判断是否存在环,并在遍历结束后找出强连通分量。算法可以在线性时间内完成,对于图的每个节点,其dfn值等于low值时,表明找到了一个强连通分量。该算法在有向图的缩点和解决2-SAT问题等领域有广泛应用。
摘要由CSDN通过智能技术生成

Tarjan 算法与有向图的连通性

Tarjan 算法是基于对图进行深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个栈,回溯时可以判断栈顶到栈中的节点是否构成一个强连通分量。

Robert E. Tarjan

Robert E. Tarjan(罗伯特·塔扬,1948~),生于美国加州波莫纳,计算机科学家。

Tarjan 发明了很多算法结构。不少他发明的算法都以他的名字命名,以至于有时会让人混淆几种不同的算法。比如求各种连通分量的 Tarjan 算法,求 LCA(Lowest Common Ancestor,最近公共祖先)的 Tarjan 算法。并查集、Splay、Toptree 也是 Tarjan 发明的。

我们这里要介绍的是在有向图中求强连通分量的 Tarjan 算法。

在正式介绍 Tarjan 算法前,有一些概念我们还需要先了解一些概念。

前置概念

给定有向图 G=(V,E)G=(V,E),若存在 r∈Vr∈V,满足从 rr 出发能够到达 VV 中所有的点,则称 GG 是一个“流图”(Flow Graph),记为 (G,r)(G,r),其中 rr 称为流图的 源点

与无向图的深度优先遍历类似,我们也可以定义“流图”的搜索树和时间戳的概念:
在一个流图 (G,r)(G,r) 上从 rr 出发进行深度优先遍历,每个点只访问一次。所有发生递归的边 (x,y)(x,y)(换言之,从 xx 到 yy 是对 yy 的第一次访问)构成一棵以 rr 为根的树,我们把它称为流图 (G,r)(G,r) 的 搜索树

同时,在深度优先遍历的过程中,按照每个节点第一次被访问的时间顺序,依次给予流图中 NN 节点 1\sim N1∼N 的整数标记,该标记被称为 时间戳,记为 dfn[x]dfn[x]。容易知道:一个结点的子树内结点的 dfndfn 都大于该结点的 dfndfn;

流图中的每条有向边 (x,y)(x,y) 必然是以下四种之一(不一定全部出现):

  1. 树枝边(tree edge),指搜索树中的边,即 xx 是 yy 的父节点。
  2. 前向边(back edge),指搜索树中 xx 是 yy 的祖先节点。
  3. 后向边(cross edge),指搜索树中 yy 是 xx 的祖先节点。
  4. 横叉边(forward edge),指除了以上三种情况之外的边,它一定满足 dfn[y]<dfn[x]dfn[y]<dfn[x](yy 在 xx 前已经被搜索过了,且不是 xx 的祖先节点)。

下图画出了一个“流图”以及它的搜索树、时间戳、边的分类。圆圈中的数字是时间戳。粗边是树枝边,并构成一棵搜索树。前向边、后向边与横叉边用第一个汉字标注。

另外一个例子:

我们考虑 搜索树(DFS 生成树)与强连通分量之间的关系。

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

反证法:假设有个结点 vv 在该强连通分量中但是不在以 uu 为根

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值