一、解释

在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。
求解有向图的强连通分量算法有很多,例如Kosaraju,Gabow和Tarjan算法,其中Gabow和Tarjan算法时间复杂度要优于Kosaraju。
理解:
如果单纯将其看出图的话有点难以理解,但是当我们将其看成树,就很容易了。

如上图,如果两个点成强联通,那么显然在树中就会存在一个环,图中L-M-J-L和A-L-M-B-A成环所以组成的强联通分量。

二、Tarjan算法

Tarjan算法基于深度优先搜索树,其有两个重要变量DFN[u]:表示在深度搜索中遍历到该节点的次序。LOW(u)表示以u节点为树根,u及u以下树节点所能找到的最小次序号。注意Tarjan认为单个节点自身就是一个强联通分量,在处理数据时注意屏蔽。以上图为例,我们从A开始,
A:DFN[1] = 1; LOW(1)=1
L:DFN[2] = 2; LOW(2)=2
M:DFN[3] = 3; LOW(3)=3
J:DFN[4] = 4; LOW(4)=4
这时我们在J节点继续往下搜索时,发现L节点我们已经搜索过了,且L:LOW(2)=2,我们发现J:LOW(4)=4>L:LOW(2)=2,因此我们将其赋值LOW(4)=2,这说明此时我们发现了一个环,代表一个强联通分量。
下面继续:
J:DFN[4] = 4; LOW(4)=2
M:DFN[3] = 3; LOW(3)=2
B:DFN[5] = 4; LOW(5)=5
发现B到A:
B:DFN[5] = 4; LOW(5)=1
开始返回更新:
M:DFN[3] = 3; LOW(3)=1
L:DFN[2] = 2; LOW(2)=1
A:DFN[1] = 1; LOW(1)=1
发现DFN=LOW(1),弹出栈。
算法:

void tarjan(int u){DFN[u]=LOW[u]=++time; //次序从1开始,初始时由于默认将DFN[u]=LOW[u]都置为次序号// 将当前节点压栈,置位在栈中,已访问。visit[u]=1;s.push(u);instack[u]=1;//取u节点的下一路径节点v,当没有v可取时也说明深度搜索已经到达当前最底部,这是我们函数返回寻找另一条路径。for(int j=0;j<G[u].size();j++){int v=G[u][j];if(visit[v]==0){tarjan(v);// 在深度搜索返回时,如果v节点下存在子树,要将u节点的LOW[u]更新。LOW[u]=min(LOW[u],LOW[v]);}else if(instack[v]){// v节点已经被访问,并且在栈中,说明在当前路径上存在环,此处只是赋值,但并不代表在u子树的底下的多个节点没有比当前环更大的环。无法作为深度终止条件。LOW[u]=min(LOW[u],DFN[v]);}}int m;int num=0; //对一个环计数计数// 在深度搜索完结后返回时,判断DFN[u]==LOW[u],相等说明找到了一个环,将栈中节点弹出。注意tarjan算法认为单个节点也为环。if(DFN[u]==LOW[u]){// 将栈中节点弹出,并计数do{m=s.top();s.pop();instack[m]=0;num++;}while(m!=u);// 只有环内节点数大于两个才是真正环。if(num>1){// n个点两两相交(互相到达),则有n*(n-1)/2条连接线total+=num*(num-1)/2;}}}

关于为啥只用访问一次:
开始疑惑,肯定会多条路径通过某一点,如果用visit记录访问记录的话,下一条路径不就会不能访问该点了吗?遂绘制丑图:

如图当我们访问到6节点时发现有环,且到达底点,这时根据算法开始返回,同时将2-6-5这条环也遍历掉(此时5号已访问压栈且有LOW=1)。也就是说在返回到1号节点开始出栈时,我们已经把1号节点的子树全部访问了一遍,该成环的也做了标记。在1号节点下的子节点不会通向1号节点以上的节点,比如0号节点,不然1号只能算一个类似于2-6-5这条环。至于从0号到5号就不用再判断了。所以遍历一遍就行。我觉得巧妙之处在于在深度向前搜索过程并没有处理数据,而在深度返回过程中开始更新数据,记录找到的回路,并且到达子树根节点DFN[u]==LOW[u]才开始出栈。
算法实例:
CCF 高速公路

图之强连通、强连通图、强连通分量 Tarjan算法相关推荐

  1. 强连通分量(Tarjan算法)和缩点

    强连通分量(Tarjan算法)和缩点 一些定义 给定一张有向图,对于图中任意两个节点 xxx 和 yyy ,存在从 xxx 到 yyy 的路径,也存在从 yyy 到 xxx 的路径,则称该有向图为强连 ...

  2. 强连通分量(Tarjan算法) 图解

    强连通分量(Tarjan算法) 前言 第一件事:没事不要while(m–),会带来不幸 第二件事:看博客先看看评论,如果博主他写错了的话- 简介 先讲几个定义 强连通:两个顶点 uuu,vvv 可以相 ...

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

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

  4. 强连通分量——tarjan算法缩点

    一. 什么是强连通分量? 强连通分量:在有向图G中,如果两个顶点u,v间(u->v)有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通(strongly connect ...

  5. 有向图的强连通分量--Tarjan算法---代码分析

    本文就是做个代码分析,顺便说下理解. 一.预备知识: 需要知道什么是: 回边.前向边.交叉边 二.上代码: #include<algorithm> #define NIL -1using ...

  6. 图论复习之强连通分量以及缩点—Tarjan算法

    图论复习之强连通分量以及缩点-Tarjan算法                                 by RtPYH ----------------------------------- ...

  7. 求无向图的连通分量或有向图的强连通分量—tarjan()ccf高速公路

    概念定义: 在图论中,连通图基于连通的概念. 1. 连通(无向图): 若顶点Vi能通过路径到达Vj,那么称为Vi和Vj是连通的 对无向图:若从顶点Vi到顶点Vj有路径相连(当然从j到i也一定有路径), ...

  8. 算法学习:强连通分量 --tarjan

    [定义] [强连通分量] 在一个子图中,任意点能够直接或者间接到达这个子图中的任意点,这个子图被称为强连通分量 [解决问题] 求图的强连通分量 同时能够起到 ...................缩点 ...

  9. HDU2767(强连通分量+Kosaraju算法)

    题意:需要加多少边才能把一个图变成强连通分量 强连通图:在有向图中,任意节点除法都可以到达其余所有节点,则称为强连通图. 强连通分量:在非强连通图的有向图中,选取部分点为强连通图,该强连通子图称为强连 ...

最新文章

  1. 使用CInternetSession和CHttpFile读取网页内容
  2. System Poles and Zeros 系统零点和极点
  3. VC中使用Matlab Engine出现无法找到libeng.dll的问题
  4. 被英特尔“冷落”的Knights Mill 悄然发布了
  5. 将InputStream写入本地文件
  6. YoloV3网络模型搭建
  7. 今天,我要在睡梦里,和死神握握手
  8. html5怎样实现信息抓取,HTML5获取定位简单方案
  9. Dapper的语法应用
  10. js基础——function类型
  11. 解决办法:NVIDIA驱动,Ubuntu16.04 用户登录界面死循环
  12. qt qtableview 刷新列表_qt qtableview基本用法
  13. HbuilderX中 华为手机 真机调试
  14. 【华为机试真题 Python实现】竖直四子棋
  15. 回归中的相关度和R平方值——学习笔记
  16. 多功能Python键盘记录工具Radium
  17. 255计算机网络,计算机网络复习题1.子网掩码为:255.255.255.一网络的为255.255.255.248,问该网络能够连接多少个...
  18. NanoPi M4开发opencv图像识别aruco码全过程(超详细)(二:测试补充)
  19. session cookie的区别最全总结
  20. 网件交换机基本配置命令

热门文章

  1. mysql data文件恢复_mysql 通过data文件下来恢复数据
  2. 微信公众号开发redirect_uri 参数错误 的解决办法,Oauth2授权重定向域名参数错误解决办法
  3. 运放专题:运放电路振铃产生的原因及解决办法
  4. mysql左连接查询 优化_【mysql 优化 5】左连接和右连接优化
  5. Android - AutoCompleteTextView (输入框动态匹配内容)
  6. 传统机器学习算法优缺点总结
  7. 鸿蒙支持ntfs,文件系统 FAT/FAT32/NTFS/ufs/ext3/reiserfs介绍
  8. Midjourney摄影真人风,超高清图片一篇足够
  9. HTMLElement.offsetParent(offsetLeft和offsetTop参照offsetParent的内边距边界)
  10. 如何制作网页2:如何学习制作网页