Tarjan算法【强连通分量】

转自:byvoid:有向图强连通分量的Tarjan算法

Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个堆栈回溯时可以判断栈顶到栈中的所有节点是否为一个强连通分量。

有两个概念:1.时间戳,2.追溯值

时间戳是dfs遍历节点的次序。

定义DFN(u)为节点u搜索的次序编号(时间戳),Low(u)为u或u的子树能够追溯到的栈中节点最小的次序号。由定义可以得出:

1 Low(u)=min{
2     DFN(u),   // 自己的次序号
3     Low(v),   //(u,v)为树枝边,u为v的父节点
4     DFN(v),   //(u,v)为指向栈中节点的后向边(非横叉边)
5 }

即以下节点的最小值:

1. 自己、子树节点的次序号

2. 指向栈中节点(后向边节点)的次序号[等价于 DFN(v)<DFN(u)且v不为u的父亲节点],这里不是横叉边(指向不在栈中的节点)。

DFN(u)=Low(u)时,以u为根的搜索子树上所有节点是一个强连通分量。

伪码:

 1 tarjan(u)
 2 {
 3     DFN[u]=Low[u]=++Index     // 为节点u设定次序编号和Low初值
 4     Stack.push(u)             // 将节点u压入栈中
 5     for each (u, v) in E      // 枚举每一条邻边
 6         if (v is not visted)  // 如果节点v未被访问过
 7             tarjan(v)         // 继续向下找
 8             Low[u] = min(Low[u], Low[v])     
 9         else if (v in S)      // 如果节点v还在栈内
10             Low[u] = min(Low[u], DFN[v])
11     if (DFN[u] == Low[u])     // 如果节点u是强连通分量的根
12         repeat
13             v = S.pop         // 将v退栈,为该强连通分量中一个顶点
14             print v
15         until (u== v)
16 }

运行Tarjan算法的过程中,每个顶点都被访问了一次,且只进出了一次堆栈,每条边也只被访问了一次,所以该算法的时间复杂度为O(N+M)

一个顶点u是割点,当且仅当满足(1)或(2)

(1) u为树根,且u有多于一个子树。

(2) u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得DFN(u)<=Low(v)。即:若某点的子树们能回到的点大于等于自己,则该点为割点

一条无向边(u,v)是,当且仅当(u,v)为树枝边,且满足DFN(u)<Low(v)。

原文地址:https://www.cnblogs.com/demian/p/9221406.html

时间: 2024-10-13 08:19:30

Tarjan算法【强连通分量】的相关文章

tarjan算法——强连通分量

简述: 用dfn作为时间戳,对图进行dfs并对路径上的点入栈,求出每个点可以访问到的最早的时间戳,此时栈中从这个点开始的点便为一个强连通分量. 模板: 1 void tarjan(int x,int lay,int &sccnum) { 2 low[x]=lay; 3 dfn[x]=lay; 4 vis[x]=1; 5 sta[++cnt]=x; 6 for(int i=head[x];~i;i=e[i].net) { 7 int v=e[i].v; 8 if(!vis[v]) tarjan(v

【学习整理】Tarjan:强连通分量+割点+割边

Tarjan求强连通分量 在一个有向图中,如果某两点间都有互相到达的路径,那么称中两个点强联通,如果任意两点都强联通,那么称这个图为强联通图:一个有向图的极大强联通子图称为强联通分量.   算法可以在 的时间内求出一个图的所有强联通分量. 表示进入结点 的时间 表示从 所能追溯到的栈中点的最早时间 如果某个点 已经在栈中则更新  否则对 进行回溯,并在回溯后更新  #include<iostream> #include<cstdlib> #include<cstdio>

CCF 高速公路 tarjan求强连通分量

问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路. 现在,大臣们帮国王拟了一个修高速公路的计划.看了计划后,国王发现,有些城市之间可以通过高速公路直接(不经过其他城市)或间接(经过一个或多个其他城市)到达,而有的却不能.如果城市A可以通过高速公路到达城市B,而且城市B也可以通过高速公路到达城市A,则这两个城市被称为便利城市对. 国王想知道,在大臣们给他的计划中,有多少个便利城市对. 输入

POJ 2553 The Bottom of a Graph(Tarjan,强连通分量)

解题思路: 本题要求 求出所有满足"自己可达的顶点都能到达自己"的顶点个数,并从小到大输出. 利用Tarjan算法求出强连通分量,统计每个强连通分量的出度,出度为0的强连通分量内的顶点即为所求顶点. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cmath

Tarjan求强连通分量、求桥和割点模板

Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using namespace std; const int maxn = 1e3 + 10; const int maxm = 330000 + 10; struct EDGE{ int v, nxt; }Edge[maxm]; int Head[maxn], cnt; int DFN[maxn], LOW[maxn],

UESTC 901 方老师抢银行 --Tarjan求强连通分量

思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个DAG(有向无环图),然后跑一遍DFS,不断加上遍历点的权值,如果到了网吧,则更新一遍答案,因为可以出去了. 求强连通分量时,如果low[u] == dfn[u],说明形成了一个新的强连通分量,且根为u.具体求强连通分量见:http://www.cnblogs.com/whatbeg/p/377642

UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】

Road Networks Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 4262 Description There is a road network comprised by M<tex2html_verbatim_mark> roads and N<tex2html_verbatim_mark> cities.

hdu 1269 tarjan求强连通分量

tarjan求强连通分量的裸题复习,直接上代码: 1 #include <stack> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int N = 10001; 7 const int M = 100000; 8 int dfn[N], low[N], head[N]; 9 bool inStack[N]; 10 int n, m, e, cnt, dfs_clock

CF949C Data Center Maintenance Tarjan找强连通分量

题意 给你\(n\)个点,每个点有一个权值\(a_x\),有\(m\)个限制条件形如\(a_x≠a_y\),现在要求你选出\(k(k>0)\)个点使其权值在模\(h\)意义下加\(1\),问最少选多少个点能让限制条件继续满足. \(Tarjan\)求强连通分量模板题 发现对于每个限制条件,如果\(a_x+1=a_y(mod\ h)\) 那么可以给\(y\)向\(x\)连一条有向边 那么最后缩点后找到入度为\(0\)的最小\(scc\)大小即可 Codes #include <cstdio>

tarjan求强连通分量(模板)

https://www.luogu.org/problem/P2341 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=50010; int pre[maxn],other[maxn],last[maxn],l; int n,m; int dfn[maxn],low[maxn],ans[maxn],st[maxn],belong[maxn