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子树

posted @ 2024-04-21 20:40  wuhupai  阅读(2)  评论(0编辑  收藏  举报