tarjan学习笔记

在 Tarjan 算法中为每个结点u维护了以下几个变量:
dfn[u]:深度优先搜索遍历时结点u被搜索的次序。
low[u]:设以u为根的子树为Subtree(u)。 low[u]定义为以下结点的dfn的最小值: 
Subtree(u)中的结点;
从Subtree(u)通过一条不在搜索树上的边能到达的结点。

如何计算low?
首先让low[x]=dfn[x](根据定义,最大也不过是dfn[x])
若在搜索树上x是y的父节点,则low[x]=min(low[x],low[y]) 递归求解
若无向边(x,y)不是搜索树上的边,则low[x]=min(low[x],dfn[y])

性质:
一个结点的子树内结点的 dfn 都大于该结点的 dfn。
从根开始的一条路径上的 dfn 严格递增,low 严格非降。

感性理解:low[x]就是从以x为根的搜索树子树内能到达的最小dfn

割边/割点

无向边(x,y)是桥(割边),当且仅当搜索树上存在x的一个子节点y,满足:dfn[x]<low[y]
感性理解:就是从y出发,一直在y的子树里转,因为y子树里的dfn都比x大

点x为割点,当且仅当存在一个点y,dfn[x]<=low[y]
若x为搜索树的根,那么要有两个点满足这个条件,因为每个点肯定都是会在这棵树里转的,如果有两个的话,两个各自在自己的子树里转就满足这个条件了(注意这是一颗dfs树,不是普通的树,每颗子树之间应该是不连通的)
感性理解:就是从y出发,一直在x的子树里转,因为x子树里的dfn都大于等于x

无向图的双连通分量

若一张无向连通图不存在割点,则称它为“点双连通图”(v-DCC)。
若一张无向连通图不存在割边,则称它为“边双连通图”(e-DCC)。
无向图的极大点双连通子图被称为“点双连通分量”
无向图的极大边双连通子图被称为“边双连通分量”

定理:一张无向连通图是“点双连通图”,当且仅当满足下列两个条件之一:
1.图的顶点数不超过2。
2.图中任意两点都同时包含在至少一个简单环中。其中“简单环‘指的是不自交的环。
定理: 一张无向连通图是“边双连通图”,当且仅当任意一条边都包含在至少一个简单环中。

感性理解即可

边双连通分量

只需求出无向图中所有桥,把桥删除后,就会分为若干个连通块,每个连通块就是一个“边双连通分量”。

有向图的缩点

如果一个点i的dfs做完后没有找到能回溯到的点,那么会有dfn[i]=low[i],i就是i所在强连通分量(树)的根节点。此时栈中的节点肯定满足这样几个条件,每个点的子树内都有指向dfn比他本身更小的节点,因为如果不是这样的话,那么在这里dfn[i]=low[i]就判定掉了。另外这些点都不会有指向前面子树的边,因为dfn[i]==low[i]。也不会有指向后面子树的边,因为这是一颗dfs树。所以这样就保证了每个点都在环上
注意,在代码中还有一个ins,代表这个点是否在栈中。这样做的目的是如果指到了一个其他强连通分量的节点那显然不能构成环

点双连通分量(无向图的缩点)

和上面类似,但因为点双和强连通分量的定义有所区别,所以不同

此时如果low[to]>=dfn[u]那么这就是一个割点,那么就将栈中的子树弹出,这颗子树里是不会有割点的,而u是割点,所以这就是极大的。而u还可能在其它点双中,不能弹出。
注意在代码中,我们没有ins因为这是求割点。然后弹的是to子树,上面弹的是u子树

缩点时是否需要instack标记取决于具体的图类型和算法需求。‌

首先求强连通分量是肯定要ins的,因为不在栈内的无法与其他构成一个强连通分量,而在求点双时因为是无向边所以可以构成。而求强连通分量时要保证恰好(点与点之间可以相互到达),所以是low[u]==dfn[u]。而点双连通分量是指在一个无向图中,‌去除任意一个顶点后,‌剩余的图仍然是连通的。‌所以是low[to]>=dfn[u]

在有向图中进行缩点操作时,‌不需要记录pre(‌前驱节点)‌,‌但需要instack标记,‌这是为了过滤“横边”,‌即那些指向当前节点但不是从已访问节点指向当前节点的边。‌这种标记帮助识别和排除那些不构成强连通分量的边,‌确保算法正确性1。‌

然而,‌在无向图中进行缩点操作时,‌需要记录pre以避免回边(‌back edge)‌,‌即节点之间的循环依赖。‌有时还需要考虑重边的情况。‌在这种情况下,‌不需要instack标记,‌因为无向图的边没有方向性,‌不需要特别标记来处理“横边”问题1。‌

对于点双连通分量的求法,‌不需要instack标记。‌这是因为点双连通分量的算法在处理无向图时,‌通过记录pre和避免回边来确保算法的正确性,‌而不需要额外的instack标记来处理“横边”1。‌

综上所述,‌是否需要instack标记取决于图的类型(‌有向图或无向图)‌以及具体的算法需求。‌在有向图的缩点算法中,‌instack标记用于过滤“横边”,‌确保算法正确性;‌而在无向图的点双连通分量求法中,‌由于通过记录pre和避免回边来处理边和节点,‌因此不需要instack标记1。‌

好多tarjan题:

P2860
意思是没有割边,即让所有边都在一个环上。可以想到先无向图按照割边缩点,形成了一棵树,然后两两连叶子,具体证明我也不会,然后连的方式大概是这样大概就是每次连边都会消掉边上的哪些链,然后就可以了。

CF1000E
必须经过边就是割边了,那么无向图按照割边缩点,形成了一棵树,然后树的直径就是答案

posted @   wuhupai  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示