口胡的笔记
关于 t a r j a n tarjan tarjan 算法,最难理解的部分应该就是里面关于 “追溯值” 也就是 l o w low low 数组的内容和几个相关的判定定理,这里我用我自己的理解梳理一遍这部分内容。
符号规定: s u b ( x ) sub(x) sub(x) 表示以 x x x 节点为根的搜索树中的子树。
无向图
定义
无向图中关于追溯值的定义是这样的:
l o w [ x ] low[x] low[x] 定义为一下节点中时间戳的最小值:
- s u b ( x ) sub(x) sub(x) 中的节点
- 通过一条不在搜索树上的边能到达 s u b ( x ) sub(x) sub(x) 的节点
注意这里的定义非常重要,关键是说清楚了 “追溯” 的含义也就是 s u b ( x ) sub(x) sub(x) 中和 通过一条不在搜索树上的边能到达 s u b ( x ) sub(x) sub(x) 的节点。
判定法则
关于割边的判定法则:若满足
d f n [ x ] < l o w [ y ] dfn[x] < low[y] dfn[x]<low[y]
则说明 ( x , y ) (x, y) (x,y) 这条边是一条割边。
现在我们画一张图来考虑证明一下这个神秘的东西:
现在我们看到上面那个椭圆 G G G 表示已经搜索过的图,下方三角形 T T T 表示的是搜索树,中间是 x x x 和 y y y 两个节点,并且满足 d f n [ x ] < l o w [ y ] dfn[x] < low[y] dfn[x]<low[y] 的条件。我们现在来判断一下这三条有虚线的边分别存不存在。
首先看 1 1 1 号边,首先 1 1 1 号边是一条从已经搜过的图中连到搜索树中的边,也就说这条边的两个节点中在 G G G 中的端点是定义中 “通过一条不在搜索树上的边能到达 s u b ( x ) sub(x) sub(x) 的节点” 。如果有这个点存在,那么 y y y 的 l o w low low 值肯定就会等于这条边中在 G G G 中的端点的 d f n dfn dfn 值,而且这个 d f n dfn dfn 值必定小于 x x x 的 d f n dfn dfn(因为那个点先被搜到),就不满足 d f n [ x ] < l o w [ y ] dfn[x] < low[y] dfn[x]<low[y] 的前提条件了,所以 1 1 1 号边肯定不存在。
同理,我们发现如果 2 2 2 号边存在,那么就有 d f n [ x ] = l o w [ y ] dfn[x] = low[y] dfn[x]=low[y],如果 3 3 3 号边存在,那么就有 d f n [ x ] < l o w [ y ] dfn[x] < low[y] dfn[x]<low[y](其实 3 3 3 号边和 1 1 1 号边是等价的)。所以我们发现这三条边(其实是三种边)都不可能存在,所以这个图中连接 G G G 和 T T T 的也就只有 G → x , x → y , y → T G \to x, x \to y, y \to T G→x,x→y,y→T 这三条边了。那么 x → y x\to y x→y 这条边就一定是割边。
关于割点的判定法则其实道理和这个也差不多,读者可以自行尝试证明一下 其实就是懒得写了qwq。
有向图
其实有向图中强连通分量的判定法则的证明和无向图中两个判定法则的证明也是类似的,所以这里大家只需要把 l o w low low 的定义弄清楚就可以了(证明可以自己下去证一下试试看)。
l o w [ x ] low[x] low[x] 定义为一下节点中时间戳的最小值:
- 在栈中的点
- 存在一条从 s u b ( x ) sub(x) sub(x) 中出发的有向边,以该节点为终点
然后,完结撒花!!!