`Computer-Algorithm` Tarjan算法,强连通分量SCC,PBCC割点,EBCC割边/桥
Contents
- EBCC
- 例题
- PBCC
- 涉及割点/PBCC时的解决思路
- 例题
- SCC
- 过去分析
- 例题
EBCC
Some properties of the algorithm:
+
for a connected-graph GGG, let EEE be the edges of its DFS-Tree, then all EPCCEPCCEPCC are the SCCSCCSCC of G−EG - EG−E; therefore perform the SCC-Algorithm on the graph G−EG - EG−E; (understand the nature of SCC algorithm is very vital, EBCC,PBCCEBCC, PBCCEBCC,PBCC are both based on it)
+
cuz all edges are undirected, for a edge (cur−nex)(cur-nex)(cur−nex), nexnexnex must be in the Stack if nexnexnex has been visited by DFS, so the array On_stack
can be removed.
例题
+
link
PBCC
Some properties of the Algorithm:
+
for a connected-graph GGG, directly perform the SCC-Algorithm on it (unlike EBCCEBCCEBCC which is acted on G−EG - EG−E not GGG), then every PBCCPBCCPBCC has the property that when we at dfs(cur)
where cur is not DFS-root and if(false == vis[nex]){ dfs( nex); if( low_id[nex] == dfs_id[cur]){ @Loc_0}}
satisfied (low_id[nex]
must always ≤\leq≤ dfs_id[cur]
); when we at @Loc_0, now all stack-points [O,cur,nex,...][O, cur, nex, ...][O,cur,nex,...] where [cur,nex,...][cur, nex, ...][cur,nex,...] forms a PBCCPBCCPBCC (cuz [root] - [cur] - [nex]
, so cur
must be a Cut-Point;) now, you need pop out all nex, ...
but keeping cur
still in the stack;
__.
one exception is cur == DFS_root
, now it becomes [cur] - [nex]
where cur
maybe not a Cut-Point (cuz it has no Father-Point), but if it has at least two DFS-Unvisited-Points, i.e., [nex1]-[cur]-[nex]
then cur
is a Cut-Point;
+
cuz all edges are undirected, for a edge (cur−nex)(cur-nex)(cur−nex), nexnexnex must be in the Stack if nexnexnex has been visited by DFS, so the array On_stack
can be removed.
涉及割点/PBCC时的解决思路
When facing a Cut-Point (PBCC) problem, you should follow the next steps:
+
if the target graph is unconnected, then divide it into all it CCCCCCs (cuz all CCCCCCs are independent to each other when handling Cut-Point), let GGG be one of its CCCCCC;
+
consider all PBCCPBCCPBCCs of GGG, rather than considering all CCCCCCs after deleting all Cut-Points from GGG;
例题
+
link
+
link
SCC
@NeedFinish, new analysis for SCC
过去分析
For a (directed) graph G=(V,E)G = (V,E)G=(V,E), let Id[v]Id[v]Id[v] is the SCC-ID of v∈Vv \in Vv∈V which within the range [0, SCC-Count).
A DFS-Order-Sequence of a graph is [0,1,2,...,n)[0, 1, 2, ..., n)[0,1,2,...,n), we use Order[v]Order[v]Order[v] represents its DFS-Order.
Let Low[v]Low[v]Low[v] denotes a DFS-Order such that Low[v]=Order[w]Low[v] = Order[w]Low[v]=Order[w] such that Order[w]≤Order[v]Order[w] \leq Order[v]Order[w]≤Order[v] and w,vw,vw,v are in the same SCC
.
If there exists a point www such that Order[w]<Order[v]Order[w] < Order[v]Order[w]<Order[v] and w,vw,vw,v in the same SCC, then Low[v]<Order[v]Low[v] < Order[v]Low[v]<Order[v]; otherwise Low[v]=Order[v]Low[v] = Order[v]Low[v]=Order[v] if and only if Order[v]Order[v]Order[v] is the minimal-Order in its SCC (every SCC has exactly one such point, we call such a point The Root of SCC).
+
e.g., G=(1→2)(2→3)(3→4)(4→3)(2→5)(5→2)(2→1)G = (1\to 2)(2\to 3)(3\to 4)(4\to 3)(2\to 5)(5\to 2)(2\to 1)G=(1→2)(2→3)(3→4)(4→3)(2→5)(5→2)(2→1) (note the order of edges is also the process of DFS(1)), then we have 222 SCC (1,2,5)(3,4)(1,2,5) (3,4)(1,2,5)(3,4); finally, Low[1]=0,Low[2]=0,Low[5]=1Low[1] = 0, Low[2] = 0, Low[5]=1Low[1]=0,Low[2]=0,Low[5]=1, all Low[v]Low[v]Low[v] in a SCC maybe not the same; Low[2]=0Low[2] = 0Low[2]=0 cuz there is Order[1]=0<Order[2]=1Order[1] = 0 < Order[2]=1Order[1]=0<Order[2]=1; Low[5]=1Low[5] = 1Low[5]=1 cuz there is Order[2]=1<Order[5]=4Order[2] = 1 < Order[5]=4Order[2]=1<Order[5]=4 (Low[5]Low[5]Low[5] can also equals Order[1]=0Order[1] = 0Order[1]=0); 000 is the root of the SCC 1,2,51,2,51,2,5)
When we at Dfs(cur)Dfs( cur)Dfs(cur) and iterating its adjacent-points nexnexnex, there are several steps:
+
Firstly, we set Order[cur] = Low[cur] = DFS_order ++
(cuz Low[cur] <= Order[cur]
finally, so we set it equals to Order[cur]
initially)
+
If nex
has never been called by DFS, so we call Dfs(nex)Dfs(nex)Dfs(nex); and then we update Low[cur]=min(self,Low[nex])Low[cur] = min(self, Low[nex])Low[cur]=min(self,Low[nex]) (cuz nex
never be DFS visited, if cur,nexcur, nexcur,nex is not in the same SCC and Order[nex]>Order[cur]Order[nex] > Order[cur]Order[nex]>Order[cur], we have nexnexnex must the Root of its SCC, so Low[nex]>Order[cur]Low[nex] > Order[cur]Low[nex]>Order[cur]; this operation is ineffective), otherwise cur,nexcur,nexcur,nex in the same SCC, if curcurcur is the Root then Low[nex]=Order[cur]Low[nex] = Order[cur]Low[nex]=Order[cur], so this operations is also ineffective; if curcurcur is not the Root, there must exists a point nex1nex1nex1 whose Low[nex1]<Order[cur]Low[nex1] < Order[cur]Low[nex1]<Order[cur] (cuz there must has a path cur→nex1→..→rootcur \to nex1 \to .. \to rootcur→nex1→..→root where ......... do not contains curcurcur, therefore Low[nex1]=Order[root]<Order[cur]Low[nex1] = Order[root] < Order[cur]Low[nex1]=Order[root]<Order[cur]);
+
When DFS returns to a root-point Low[] = Order[]
, then the DFS-Stack must be in the form [...., root, S]
where any point that in the same SCC with root
, must occurs in S
;
Code
void dfs( int _cur){queue[ tail ++] = _cur;isInQueue[ _cur] = true;dfsOrderId[ _cur] = dfsOrderId_counter ++;lowest_orderId[ _cur] = dfsOrderId[ _cur];//--for( int nex, i = graph->Head[ _cur]; ~i; i = graph->Next[ i]){nex = graph->Vertex[ i];if( -1 == dfsOrderId[ nex]){ //< never `dfs( nex)` calleddfs( nex);}if( isInQueue[ nex]){ //< `nex` maybe already forms a SCC, we should aviod this case; e.g., (1<->2)<-3, so Low[2] cann't be used to updated Low[3]lowest_orderId[ _cur] = min( lowest_orderId[ nex], lowest_orderId[ _cur]);}}if( lowest_orderId[ _cur] == dfsOrderId[ _cur]){scc_size[ scc_id_counter] = 0;while( true){int c = queue[ tail - 1];isInQueue[ c] = false;-- tail;scc_id[ c] = scc_id_counter;++ scc_size[ scc_id_counter];if( c == _cur){ break;}}++ scc_id_counter;}
}
Actually, the array dfsOrderId, lowest_orderId
can be omitted; (use scc_id
to denote lowest_orderId
, cuz when DFS not yet returned to root
, the array scc_id
is free; and once a SCC is fixed (i.e., DFS has returned to its root
, any other points (not belongs to this SCC) would not visit/use any information of this SCC)
void dfs( int _cur){ptrNew_queue[ queue_tail ++] = _cur;ptrNew_isInQueue[ _cur] = true;int current_dfsOrderId = dfsOrderId_counter;ptrNew_sccId[ _cur] = dfsOrderId_counter ++;//--for( int nex, i = ptrRef_graph->Head[ _cur]; ~i; i = ptrRef_graph->Next[ i]){nex = ptrRef_graph->Vertex[ i];if( -1 == ptrNew_sccId[ nex]){ //< never `dfs( nex)` calleddfs( nex);}if( ptrNew_isInQueue[ nex]){ptrNew_sccId[ _cur] = min( ptrNew_sccId[ nex], ptrNew_sccId[ _cur]);}}if( ptrNew_sccId[ _cur] == current_dfsOrderId){ptrNew_sccSize[ scc_id_counter] = 0;while( true){int c = ptrNew_queue[ queue_tail - 1];ptrNew_isInQueue[ c] = false;-- queue_tail;ptrNew_sccId[ c] = scc_id_counter;++ ptrNew_sccSize[ scc_id_counter];if( c == _cur){ break;}}++ scc_id_counter;}
}
例题
+
link
`Computer-Algorithm` Tarjan算法,强连通分量SCC,PBCC割点,EBCC割边/桥相关推荐
- nyist120 校园网络 (Tarjan算法 / 强连通分量)
校园网络(nyist 120) 解题思路请看代码块中的注释~ import java.util.Scanner; import java.util.Stack; import java.util.Ve ...
- tarjan算法总结 (强连通分量+缩点+割点),看这一篇就够了~
文章目录 一.tarjan求强连通分量 1:算法流程 2:模板 二.tarjan缩点 1:相关定义 2:算法流程 三.tarjan求割点.桥 1.什么是割点 2.割点怎么求? 3.割点tarjan模板 ...
- Tarjan有向图强连通分量
Tarjan有向图强连通分量 本文仅供娱乐,不喜勿喷 一.强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi ...
- 有向图强连通分量SCC(全网最好理解)
定义: 在有向图中,如果一些顶点中任意两个顶点都能互相到达(间接或直接),那么这些顶点就构成了一个强连通分量,如果一个顶点没有出度,即它不能到达其他任何顶点,那么该顶点自己就是一个强连通分量. 做题的 ...
- The King’s Problem(tarjan求强连通分量缩点+匈牙利求有向无环图的最小路径覆盖)
Link:http://acm.hdu.edu.cn/showproblem.php?pid=3861 The King's Problem Time Limit: 2000/1000 MS (Jav ...
- 洛谷 P2921 在农场万圣节Trick or Treat on the Farm (tarjan求强连通分量)
洛谷 P2921 在农场万圣节Trick or Treat on the Farm (tarjan求强连通分量) 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N&l ...
- hdu 1269 tarjan求强连通分量
tarjan求强连通分量的裸题复习,可当做模板. 1 #include <stack> 2 #include <cstdio> 3 #include <cstring&g ...
- Tarjan 算法思想求强连通分量及求割点模板(超详细图解)
割点定义 在一个无向图中,如果有一个顶点,删除这个顶点及其相关联的边后,图的连通分量增多,就称该点是割点,该点构成的集合就是割点集合.简单来说就是去掉该点后其所在的连通图不再连通,则该点称为割点. 若 ...
- 【HDU - 4635】Strongly connected(缩点,新图性质,建图,Tarjan求强连通分量)
题干: Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the ...
最新文章
- 42、使用存放在存assets文件夹下的SQLite数据库
- MVC开发中的常见错误-06-无法在发送 HTTP 标头之后进行重定向。
- shell中while循环案例
- How to hide index.php on nginx
- C++11:using 的各种作用
- Execution Order of Event Functions, unity 3d 事件函数的执行顺序
- 使用springboot集成jseesite
- layui怎样将响应数据展示在页面_layui怎么对弹出层显示数据
- 正常使用 flex profiler 解决 Socket timeout
- 成功的捷径,学会这一点,赚钱很容易
- java类包装器有什么用_Java中的包装器类
- 易班显示服务器错误,重新认识一下,这里是易班
- Java开发实习生面试—附简历以及面试题
- Delcam PowerInspect 5040 sp1/
- IP地址转换与域名解析
- Adams_2019_x64
- angular使用jqwidgets注意事项
- 无轴螺旋输送机的安装可是一门技术活
- 计算机模拟在数学实验报告,MATLAB实验-8计算机模拟.doc
- DVWA关卡11:Reflected Cross Site Scripting (XSS)(反射型XSS)
热门文章
- python-3d绘图包VPython
- ElementUI使用表格如何显示图片?
- icoud邮箱无法连接服务器,适用于 iCloud 电子邮件客户端的邮件服务器设置
- 74ls161芯片介绍和使用方法(不讲原理)
- 关于数学计算机手抄报简单的,简单漂亮的数学手抄报图片大全
- c# - 作业4:中国象棋
- 【MATLAB教程案例13】基于SA模拟退火优化算法的函数极值计算matlab仿真及其他应用
- WebSocket 进阶:把屏幕分享到浏览器
- poj2502 SubWay
- 论文Depth Information Guided Crowd Counting for Complex Crowd Scenes