在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下:

首先解释几个概念:

有向图强连通分量:在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。

如果有向图G的每两个顶点都强连通,则称G是一个强连通图。

非强连通图有向图的极大强连通子图,成为强连通分量(strongly connected components)。

下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达,{5},{6}也分别是两个强连通分量。

求强连通分量的Tarjan算法如下

Targin算法

算法的基本思想如下,任选图中的一个点开始进行深度优先搜索,并按访问的顺序对点u进行编号,将结果存在数组index[u]中。另一个数组low,存储u或u的子树能够追溯到最早的栈中节点的次序号。对于一个边(u,v)我们可得

low(u) = MIN{
index(u),
index(v), v还在栈中,此时还没有算完low(v)
low(v) ,u为v的父节点,v未被访问
}

当index[u] = low[u]时,以u为根的子树上的所有节点是一个强连通分量

算法的伪代码如下

tarjan(u)
{
index[u]=low[u]=++tmp // 为节点u设定次序编号和low初值,tmp从0开始
Stack.push(u) // 将节点u压入栈中
for each (u, v) in E // 枚举每一条边
if (v is not visted) // 如果节点v未被访问过
tarjan(v) // 继续向下找
low[u] = min(low[u], low[v])
else if (v in Stack) // 如果节点v还在栈内
low[u] = min(low[u], index[v])
if (index[u] == low[u]) // 如果节点u是强连通分量的根
repeat
v = Stack.pop // 将v退栈,为该强连通分量中一个顶点
print v
until (u == v)
}

算法应用举例

NODE  INDEX  LOW

1     0     0(未算完)

2    

3    1     1(未算完)

4    

5    2     2(未算完)

6    3              3(未算完)

{6}为一个强连通分量

NODE  INDEX  LOW

1     0     0(未算完)

2    

3    1     1(未算完)

4    

5    2     2

{5}为一个强连通分量

NODE  INDEX  LOW

1     0     0(未算完)

2    

3    1     1(未算完)

4    4              0

NODE  INDEX  LOW

1     0     0

2    5     5

3    1     0

4    4              0

{1,2,3,4}为一个强连通分量,算法结束

算法的复杂度为

O(N+M),边数+结点数

最新文章

  1. CocoaPods安装和使用
  2. webpack详细配置讲解
  3. 用Join子句进行分组联接
  4. python序列化模块json和pickle
  5. Html.RenderPartial、Html.RenderAction联系与区别
  6. java.lang.reflect.Method
  7. android操作XML的几种方式(转)
  8. PHP - 5.4 Array dereferencing 数组值
  9. Java8中Lambda表达式的10个例子
  10. 实现Asp.net Mvc分布式Session Redis群集
  11. Leetcode题解(十三)
  12. remove the nth node from the end of the list
  13. 关系型数据库中主键(primary key)和外键(foreign key)的概念。
  14. JVM和GC垃圾回收机制和内存分配
  15. EOS智能合约开发(四):智能合约部署及调试(附编程示例)
  16. hisicv200 exfat支持
  17. mysql 5.7 ~ 新特性
  18. Javascript学习笔记5 - 滑动Slides
  19. linux怎么执行jar文件 怎么打可执行的jar包
  20. 正则和xpath在网页中匹配字段的效率比较

热门文章

  1. hadoop分类输出
  2. C# unchecked运算符
  3. 微信小程序清除默认样式
  4. python实现简单分类knn算法
  5. 【c学习-4】
  6. 微信小程序本地缓存
  7. python3 练习题100例 (十八)托儿所问题
  8. APUE中对出错函数的封装
  9. Educational Codeforces Round 42D. Merge Equals(STL)
  10. MongoDb第一天