简单理解Tarjan算法

  按照百度百科的播报应该是读成【'ta:rdʒən】?看过了几篇网络上的解释虽然都讲得比较具体但刚开始都难以理解,所以打算写一个更直观的理解方式。
  Tarjan算法是求有向图中的强连通分量的算法。关于有向图和强连通分量的概念借鉴强连通分量:
  在有向图G中,如果两个顶点u,v间有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向非强连通图的极大强连通子图,称为强连通分量。

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

一、Tarjan算法的原理:

采用讲解这个算法时最常用的图来讲解:

当从结点1开始深度优先遍历有向图时,会产生以下的树形图:

1.1 树的产生过程为:

从结点1出发,经过右边的出度到达2结点;
从2结点,经过右边的出度到达3结点;
从3结点经过下面的出度到达6结点;
6结点无出度,回溯到3结点;
3结点无出度,回溯到2结点;
2结点经过下面的出度到达5结点;
5结点有指向已访问结点6的出度,标红;
5结点有指向已访问结点1的出度,标蓝;
5结点无出度,回溯到2结点;
2结点无出度,回溯到1结点;
1结点经过下面的出度到达4结点;
4结点有指向已访问结点5的出度,标蓝;

1.2 基本原理:

1、可以看出图中DFN[i]的值就是结点加入树形图的顺序,相当于每一个结点的标识符。

2、在访问至5结点时,有两个指向已访问结点的出度。其中一条红色的指向6结点,一条蓝色的指向1结点。红色出度未能形成强连通图,而蓝色出度导致{5,1,2}形成回路,也就是强连通图。 形成连通图的原理是树本身是单向连通的,若有子节点指向父(祖宗)节点便能形成回路,即强连通图。

3、4的出度指向5,并不是其父节点但也形成强连通图{1,2,5,4}。原因是5结点和1结点已经是强连通,4指向5相当于4指向1,即指向父(祖宗)节点。

那么如何判断指向的是否是父(祖宗)节点或是与祖宗节点强连通的子节点呢?

  这就要用到栈的帮助,栈的含义是:存储所有可能是在同一强连通图中的元素,同时出栈的则属于同一强连通图。首先看下面的图:

  显然我们增加了一个LOW数据结构,它的意义是存储所在强连通图的根节点标识符(也就是DFN派上用场的时候了),具体更新和判断过程是这样的:

1、在深度优先遍历图时,每遍历到一个结点便为它生成LOW[i]=DFN[i]=++index,(意思是初始时i结点的位置标识为递归遍历的顺序index,且初始时根节点为自身)入栈;

2、当这个结点没有出度时,深度优先将要回溯:
  回溯到父节点时考虑子节点的LOW是否小于自己的LOW若小于则修改LOW(含义是子节点所在强连通图的根节点一定也是自己强连通图的根节点,如LOW[2]=LOW[5]=1。
  再考虑栈中该结点是否要出栈,若LOW[i]==DFN[i]则说明自己便是一个强连通图的根节点,于是便可将此结点及其后续结点都出栈。(如图中6,3结点,包括最后出栈的1结点出栈时将2、4、5结点都出栈)。一同出栈的便构成一个强连通图。

3、当结点的出度指向已访问且已出栈的结点时:如图中红线,则不做处理。

4、当结点的出度指向已访问且未出栈的结点时:如图中蓝线,则将此节点的LOW[]改为该结点的LOW。(如LOW[5]=LOW[1]=5、 LOW[4]=LOW[5]=1),表示修改该节点所在的强连通图的根节点。

5、当结点的出度指向未访问的结点时,则按照1进行。

二、伪代码:

  搬来伪代码给大家看看:

tarjan(u){DFN[u]=Low[u]=++Index // 为节点u设定次序编号和Low初值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 S) // 如果节点u还在栈内Low[u] = min(Low[u], DFN[v])if (DFN[u] == Low[u]) // 如果节点u是强连通分量的根repeat v = S.pop  // 将v退栈,为该强连通分量中一个顶点print vuntil (u== v)}

参考链接:1、全网最!详!细!tarjan算法讲解
      2、强连通分量

直观地简单理解Tarjan算法(寻找有向图中的强连通图)相关推荐

  1. C++用Tarjan 算法寻找桥(附完整源码)

    C++用Tarjan 算法寻找桥的实现 C++用Tarjan 算法寻找桥完整源码(定义,实现,main函数测试) C++用Tarjan 算法寻找桥完整源码(定义,实现,main函数测试) #inclu ...

  2. 算法-寻找数组中的重复值,四种解法

    算法-寻找数组中的重复值 寻找数组中的重复值 寻找数组中的重复值 题目来源于:Leetcode-287.本题归类到简单我无法理解-要满足四个条件需要用很特定的解法,面试中要是用到的话很可能是在给自己挖 ...

  3. 简单理解蒙特卡洛算法

    1.概述 蒙特卡洛算法,是二十世纪四十年代中期由于科学技术的发展和电子计算机的发明,而被提出的一种以概率统计理论为指导的一类非常重要的数值计算方法.是指使用随机数来解决很多计算问题的方法.利用若干个随 ...

  4. 信号处理中简单实用的方法——寻找信号中的峰值和谷值

    在信号处理中,经常会需要在时间域或频率域寻找峰值和谷值.MATLAB工具箱中已有峰值检测的函数(findpeaks函数),本次将结合函数说明对峰值和谷值的检测. 如果只找一个峰值可以用max函数,而需 ...

  5. 简单理解Tomasulo算法与重加载缓冲区

    参考书:<计算机体系结构量化研究方法> 作者:John L. Hennessy 流水线运行的一个主要限制是:它们使用循序指令发射与执行的方式.把指令执行的流水线简单比喻为洗衣服: 采用循序 ...

  6. 简单理解viterbi算法

    简介: viterbi算法其实就是多步骤每步多选择模型的最优选择问题,其在每一步的所有选择都保存了前续所有步骤到当前步骤当前选择的最小总代价(或者最大价值)以及当前代价的情况下前继步骤的选择.依次计算 ...

  7. 简单理解在线性函数的估计中bias(偏差)与variance(方差)的影响

    对于估计所需求的函数,我们可以从自己所设定的n个函数中挑出一个误差与真实值相差的误差最小的函数 f ∗ ( x ) \color{blue}{f^*}(x) f∗(x),但是这个函数不一定是真实情况对 ...

  8. 简单理解函数f(x;θ)中分号的含义

    注,本文理解可能有不准确甚至有误的地方,仅供参考 我们知道,f(x)f(x)f(x)其实就是一个函数,输入变量值xxx,在经过规则fff处理后,最终拿到一个结果. 另一种常见的情况是,比如概率分布P( ...

  9. 有向图强连通分量tarjan算法

    转自:http://www.byvoid.com/blog/scc-tarjan/ http://blog.csdn.net/geniusluzh/article/details/6601514 在有 ...

最新文章

  1. NASA发现超级地球,真的适宜居住?
  2. springboot日志的级别
  3. MySQL的事务与事务隔离
  4. git同时推送项目到GitHub和Gitee
  5. Python模拟汉诺塔问题移动盘子的过程
  6. 无论你是用什么样的模式去拓展市场
  7. 获取所有股票历史数据存到Excel
  8. android 微信自带表情,Android 软键盘和emoji表情切换方案,和微信几乎一样的体验...
  9. 计算机与现代社会英语作文,高一英语作文,科技以下是题目:众所周知,科技在现代社会和生活中扮演着越来越重要的角色,但科技同时也是一把双刃剑,在它璀璨...
  10. Spring学习传送门
  11. oracle统计每个员工数,oracle按部门统计员工人数
  12. 项目2-Time类中的运算符重载
  13. Http请求加密规则(3DES、Base64、HMAC SHA256)
  14. Python 阴阳师/pillow-窗口截屏/opencv-图像识别/pyaotugui-点击/pyqt5-UI界面设计/pyqt5-窗口绘制
  15. java技术及ssh框架和jsp技术的介绍 外文文献及翻译_java技术及ssh框架和jsp技术的介绍 外文文献及翻译.doc...
  16. 堆栈溢出:Stack overflow (参数: 0x0000000000000001, 0x0000005410A03FF8)
  17. 如何选择有效的CRM软件解决方案
  18. leetcode 695. 岛屿的最大面积 python
  19. 最新自适应手机端CRM客户关系管理系统
  20. 视频去水印怎么去?这几款视频去水印工具推荐给你

热门文章

  1. 微信将整顿多级分销欺诈行为 严重者将永久封号
  2. 廖雪峰python3复习总结——day7-4
  3. 大咖实战分享 | 实现中小微企业金融服务场景经验分享
  4. 公司财务会计制度范本
  5. H96 max+ RK3328 刷机完整过程
  6. java计算机毕业设计建材公司管理系统(附源码、数据库)
  7. 魏则西事件后推广模式有所改变,SEO优化对企业显得尤为重要
  8. 检测selenium下载文件
  9. 2020年绿色建筑政策汇总 绿色建筑的发展不可小觑
  10. 先验概率、后验概率和似然概率