图的连通性——Tarjan算法&割边&割点

tarjan算法

原理:

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

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

反证法:假设有个结点 在该强连通分量中但是不在以 为根的⼦树中,那么 到 的路径中肯 定有⼀条离开⼦树的边。但是这样的边只可能是横叉边或者反祖边,然⽽这两条边都要求指向的结点已 经被访问过了,这就和 是第⼀个访问的结点⽭盾了。得证。

思路:

在 Tarjan 算法中为每个结点 维护了以下⼏个变量:

1:dfn[u]深度优先搜索遍历时结点 的DFS序。

2:low[u]设以u为根的⼦树为Subtree[u]。low[u]定义为以下结点的dfn的最⼩值:

Subtree(u)中的结点;从 Subtree(u)通过⼀条不在搜索树上的边能到达的结点。

遍历时维护栈,⽤于求解强连通分量。 ⼀个结点的⼦树内结点的 dfn 都⼤于该结点的 dfn。 从根开始的⼀条路径上的 dfn 严格递增,low 严格⾮降。 按照深度优先搜索算法搜索的次序对图中所有的结点进⾏搜索。

在搜索过程中,对于结点u和与其v相邻的结点 考虑 3 种情况:

  1. v未被访问:继续对v进⾏深度搜索。在回溯过程中,low[v]⽤low[u]更新 。因为存在从u到v的直接路径,所以v 能够回溯到的已经在栈中的结点,u也⼀定能够回溯到。

  2. v被访问过,已经在栈中:即已经被访问过,根据low值的定义(能够回溯到的最早的已经在栈中 的结点),则⽤dfn[u]更新low[v] 。

  3. v被访问过,已不在在栈中:说明v已搜索完毕,其所在连通分量已被处理,所以不⽤对其做操作。

posted @ 2021-02-09 18:40  xialuo  阅读(103)  评论(0)    收藏  举报