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割边/桥相关推荐

  1. nyist120 校园网络 (Tarjan算法 / 强连通分量)

    校园网络(nyist 120) 解题思路请看代码块中的注释~ import java.util.Scanner; import java.util.Stack; import java.util.Ve ...

  2. tarjan算法总结 (强连通分量+缩点+割点),看这一篇就够了~

    文章目录 一.tarjan求强连通分量 1:算法流程 2:模板 二.tarjan缩点 1:相关定义 2:算法流程 三.tarjan求割点.桥 1.什么是割点 2.割点怎么求? 3.割点tarjan模板 ...

  3. Tarjan有向图强连通分量

    Tarjan有向图强连通分量 本文仅供娱乐,不喜勿喷 一.强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi ...

  4. 有向图强连通分量SCC(全网最好理解)

    定义: 在有向图中,如果一些顶点中任意两个顶点都能互相到达(间接或直接),那么这些顶点就构成了一个强连通分量,如果一个顶点没有出度,即它不能到达其他任何顶点,那么该顶点自己就是一个强连通分量. 做题的 ...

  5. 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 ...

  6. 洛谷 P2921 在农场万圣节Trick or Treat on the Farm (tarjan求强连通分量)

    洛谷 P2921 在农场万圣节Trick or Treat on the Farm (tarjan求强连通分量) 题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N&l ...

  7. hdu 1269 tarjan求强连通分量

    tarjan求强连通分量的裸题复习,可当做模板. 1 #include <stack> 2 #include <cstdio> 3 #include <cstring&g ...

  8. Tarjan 算法思想求强连通分量及求割点模板(超详细图解)

    割点定义 在一个无向图中,如果有一个顶点,删除这个顶点及其相关联的边后,图的连通分量增多,就称该点是割点,该点构成的集合就是割点集合.简单来说就是去掉该点后其所在的连通图不再连通,则该点称为割点. 若 ...

  9. 【HDU - 4635】Strongly connected(缩点,新图性质,建图,Tarjan求强连通分量)

    题干: Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the ...

最新文章

  1. 42、使用存放在存assets文件夹下的SQLite数据库
  2. MVC开发中的常见错误-06-无法在发送 HTTP 标头之后进行重定向。
  3. shell中while循环案例
  4. How to hide index.php on nginx
  5. C++11:using 的各种作用
  6. Execution Order of Event Functions, unity 3d 事件函数的执行顺序
  7. 使用springboot集成jseesite
  8. layui怎样将响应数据展示在页面_layui怎么对弹出层显示数据
  9. 正常使用 flex profiler 解决 Socket timeout
  10. 成功的捷径,学会这一点,赚钱很容易
  11. java类包装器有什么用_Java中的包装器类
  12. 易班显示服务器错误,重新认识一下,这里是易班
  13. Java开发实习生面试—附简历以及面试题
  14. Delcam PowerInspect 5040 sp1/
  15. IP地址转换与域名解析
  16. Adams_2019_x64
  17. angular使用jqwidgets注意事项
  18. 无轴螺旋输送机的安装可是一门技术活
  19. 计算机模拟在数学实验报告,MATLAB实验-8计算机模拟.doc
  20. DVWA关卡11:Reflected Cross Site Scripting (XSS)(反射型XSS)

热门文章

  1. python-3d绘图包VPython
  2. ElementUI使用表格如何显示图片?
  3. icoud邮箱无法连接服务器,适用于 iCloud 电子邮件客户端的邮件服务器设置
  4. 74ls161芯片介绍和使用方法(不讲原理)
  5. 关于数学计算机手抄报简单的,简单漂亮的数学手抄报图片大全
  6. c# - 作业4:中国象棋
  7. 【MATLAB教程案例13】基于SA模拟退火优化算法的函数极值计算matlab仿真及其他应用
  8. WebSocket 进阶:把屏幕分享到浏览器
  9. poj2502 SubWay
  10. 论文Depth Information Guided Crowd Counting for Complex Crowd Scenes