定义:在一张有向图中,两个点可以相互到达,则称这两个点强连通;一张有向图上任意两个点可以相互到达,则称这张图为强连通图;非强连通图有极大的强连通子图,成为强联通分量。

如图,{1},{6}分别是一个强连通分量,{2,3,4,5}是一个强连通分量。而Tarjan算法可用于求解强连通分量。


Tarjan算法

Tarjan算法是基于深度优先搜索的算法,每个强连通分量都是搜索树中的一个子树。

实现:dfn[u]表示到u节点时的标记(时间戳),low[u]表示u所能走到的节点中,点的最小的次序号(dfn),每搜寻一个节点u,就把一个节点入栈,令dfn[u]=++it;low[u]=dfn[u]。u所连接的节点为v,若v已经被搜寻过,则low[u]=min(low[u],low[v])。若v没有被搜寻过,则dfs(v)low[u]=min(low[u],low[v])。搜寻完u所连接的所有的边后,若dfn[u]==low[u],则u这个点是该点所在强连通分量中编号最小的点。此时栈里的u节点上面的全部为该强连通分量的节点。

第一步:

点1有一条边指向2号点,而且2号点没有被遍历,dfs(2)。

第二步

2有一条边指向3,遍历三号点。

第三步:

3指向4,dfs(4)。

第四步:

dfs(5)。

第五步:

5号点存在两条边,两条边都要遍历,假设先走到2号点的边。因为2号点已经遍历过,所以直接比较即可,这时候要更新5号点的low。

第六步:

然后遍历6号节点。

第七步:

此时6号节点无法向外扩展节点,此时dfn[6]==low[6],因此6号节点就是一个强连通分量。弹出6号节点,回溯。此时图的遍历已经完成,所有的节点均已被打上标记。

第八步:

回溯到5号节点,low[5]!=dfn[5],继续回溯。

第九步:

回溯到4号节点,更新4号节点的low值。

第十步:

回溯到3号节点,更新3号的low值。

第十一步:

回溯到2号节点,此时low[2]==dfn[2],因此,栈中2号点上面的(包括2号点)全部在一个强连通分量中。将他们全部弹出。

第十二步:

回溯到1号节点,dfn[1]==low[1],因此1号节点也是一个强连通分量。弹出。

void tarjan(int u){
dfn[u]=++it;
low[u]=it;
for(int i=;i<tu[u].size();i++){
if(!in[tu[u][i]]){
in[tu[u][i]]=true;
s.push(tu[u][i]);
tarjan(tu[u][i]);
low[u]=min(low[u],low[tu[u][i]]);
}
else{
low[u]=min(low[u],low[tu[u][i]]);
}
}
if(low[u]==dfn[u]){
while(s.top()!=u){
s.pop();
}
s.pop();
}
}

强联通分量-tarjan算法的更多相关文章

  1. 有向图的强联通分量 Tarjan算法模板

    //白书 321页 #include<iostream> #include<cstdio> #include<cstring> #include<vector ...

  2. 强联通块tarjan算法

    http://poj.org/problem?id=1236第一问:需要几个学校存在软件,才能通过传递,使得所有的学校都有软件 用tarjan算法求出强联通分量后,将每个联通分量缩成一个点,那么问题1 ...

  3. [vios1023]维多利亚的舞会3<强联通分量tarjan>

    题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...

  4. POJ 2186-Popular Cows (图论-强联通分量Korasaju算法)

    题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认 ...

  5. POJ 3592 Instantaneous Transference(强联通分量 Tarjan)

    http://poj.org/problem?id=3592 题意 :给你一个n*m的矩阵,每个位置上都有一个字符,如果是数字代表这个地方有该数量的金矿,如果是*代表这个地方有传送带并且没有金矿,可以 ...

  6. POJ 3114 Countries in War(强联通分量+Tarjan)

    题目链接 题意 : 给你两个城市让你求最短距离,如果两个城市位于同一强连通分量中那距离为0. 思路 :强连通分量缩点之后,求最短路.以前写过,总感觉记忆不深,这次自己敲完再写了一遍. #include ...

  7. poj-3177(并查集+双联通分量+Tarjan算法)

    题目链接:传送门 思路: 题目要将使每一对草场之间都有至少两条相互分离的路径,所以转化为(一个有桥的连通图至少加几条边才能变为双联通图?) 先求出所有的桥的个数,同时将不同区块收缩成一个点(利用并查集 ...

  8. hdu 1269 (强联通分量Tarjan入门)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  9. Tarjan的强联通分量

    求强联通分量有很多种. <C++信息学奥赛一本通>  中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说 ...

随机推荐

  1. Appium基础知识与环境搭建

    基础知识:  环境搭建: 1.安装jdk,配置java环境变量 (1)新建变量"JAVA_HOME",变量值"D:\Frameworks\Java\jdk1.8.0_18 ...

  2. 项目集成swagger【转载】

    地址链接:https://blog.csdn.net/lx1309244704/article/details/81808788 swagger是一款高效易用的嵌入式文档插件,同时支持在线测试接口,快 ...

  3. linux上部署jenkins步骤小记

    一.部署jdk环境 1.下载jdk包,解压,放在选定的位置,我本次jdk包放置在“/usr/local/java/jdk” 目录下 2.配置环境变量 1)打开/etc/profile文件,在命令框中输 ...

  4. java script简介

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  5. 如何在Mac上用汇编语言写HelloWorld

    首先,Mac自带nasm,不过我们要先将其升级. 升级它的方法有很多种,因为我已经装好了homebrew,所以我直接在终端输入: brew install nasm 这样就升级啦- 接下来,创建一个H ...

  6. linux下的dhcp服务器实现

    一.得到udhcpd(udhcp服务端): 1.解压busybox 2.配置busybox Networking Utilities——> [*] udhcp server(udhcpd) [* ...

  7. Java基础(命令行操作、注释及API、)

    一.常用的dos命令. dir:列出当前目录下的文件及文件夹 md:创建目录 rd:删除目录 cd:进入到指定目录 cd..:退出到上一级目录 cd\:退出到根目录 del:删除文件 exit:退出d ...

  8. Python之Unittest和Requests库详解

    1.按类来执行 import unittest class f1(unittest.TestCase): def setUp(self): pass def tearDown(self): pass ...

  9. Servlet第五篇(会话技术之Session)

    Session 什么是Session Session 是另一种记录浏览器状态的机制.不同的是Cookie保存在浏览器中,Session保存在服务器中.用户使用浏览器访问服务器的时候,服务器把用户的信息 ...

  10. cacti 流量图合并

    cacti 安装:https://www.cnblogs.com/weijie0717/p/4072711.html 一.需求介绍 由于交换机的多端口跑同一种流量,需要汇总统计.因此需要见多个端口的流 ...