Tarjan 算法学习笔记
无向图上的 Tarjan
定义:
:点 的时间戳,记录点 是 DFS 过程中被访问的时间。 :记录点 经过至多一条非树边,所能达到的 dfn 最小的节点。
对于 DFS 中每一条遍历到的边
- 若搜索树上
是 的儿子,即边 是树边,则有 。 - 否则边
一定是返祖边,即 是 的祖先,则有 。 - 可以发现对无向图进行 DFS 遍历时,是不可能存在横叉边的。
割点#
一个点是割点的充要条件是:
- 若点
为搜索树的根,且 有两个以上的儿子,则 是割点。 - 否则,如果存在
的一个儿子 ,满足 ,则 是割点。
点双连通分量#
- DFS 过程中,用栈来存储被访问过的点。
- 对于点
,如果它的儿子 满足 ,则 是割点。不断弹栈,直到弹出 ;此时弹出的点和 就构成了一个点双。 - DFS 结束后,栈中剩下的点们构成一个点双。
- 割点会存在于多个点双之中,其他点以及每一条边只会存在一个点双里。
割边#
- 首先非树边不可能成为割边。
- 对于树边
,其中 是 的父亲;如果 ,则边 是割边。 - 或者如果
,则 和 的父亲之间的树边是割边。 - 原理就是如果
无法通过返祖边和 的祖先联通,则 是割边。
边双连通分量#
- 同样建立栈,将遍历到的点依次压入栈中。
- 如果
,则 和 的父亲是割边;则不断弹栈,直到弹出点 。然后将这些刚弹出的点归入一个边双中。 - 割边不会存在于任何一个边双里;其余边和所有点会恰好存在于一个边双里。
- 容易发现,缩完点后的图会变成一棵优美的树。
有向图上的 Tarjan
定义:
:点 的时间戳,记录点 是 DFS 过程中被访问的时间。 :记录点 经过至多一条返祖边,所能达到的 dfn 最小的节点。
强连通分量#
定义:
- 如果两个点 u,v,存在 u 到 v 的路径,且存在 v 到 u 的路径,则称这两个点强连通。
- 所有点都强连通的图称为强连通图。
- 我们把图中极大的强连通子图称为强连通分量。
求法:
- 同样开一个栈,将 dfs 到的点依次压入栈里面。
- 每次更新
时,如果是横叉边且那个点无法回到 的某个祖先(即那个点不在栈里面)则无视。 - 当
时,则不断弹栈,直到弹出 ,然后将这些点归入一个 SCC 中。 - 缩完点后的图是个 DAG。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】