Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ)
Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点
首先给出强连通分量的定义:
若在有向图G中 存在u到v的路径的同时也存在v到u的路径 则称u与v是强连通的 若G中所有点之间两两之间是强连通的则称G为一个强连通图 一个有向非强连通图的极大强连通子图称为强连通分量
极大强连通子图:G是一个极大强连通子图 当且仅当G是一个强连通图 同时不存在另一个强连通图G'使G是它的真子集
下面 的2 3 4 三个点构成一个强连通分量 同时1也是一个强连通分量
通过观察强连通分量的定义我们可以发现 如果通过dfs遍历含有强连通分量的图 一个点可能与它的子节点在同一个强连通分量中 或者与父节点在同一个强连通分量 若点V延伸出的dfs搜索树中有节点跟V有连边就意味着这个节点回溯回来的路径上的所有点与V强连通 同时点V延伸的搜索树中不一定只有一个节点满足这样的条件 而当把这样的节点找全以后 就求出了以V节点为根节点的搜索树中所有与V强连通的点
但是这样操作并没有考虑V的父节点或祖父节点即此时求得的并不一定是一个强连通分量只能说明这些点强连通 但最终一定能求出包含dfs起点的强连通分量(以dfs起点为根节点的搜索树中必定包含所有与起点强连通的点)
但若要求求出所有强连通分量 则不管算法的时间复杂度 求出整张图的强连通分量需要暴力枚举每一个点才能得到所有强连通分量 而这样时间复杂度会达到n2 级别
看起来不错但操作过于暴力所以让我们想一想有没有更好的做法?在遍历V的搜索树时 它的子节点不仅可能有边连接V 还可能连接到V的父节点或祖先节点或其他与V强连通的点 有没有什么方法能够利用这一点来简化算法?或者怎样唯一确定V是一个强连通分量的根节点?(确定一个点V 而所有与V强连通的点在以V为节点的搜索树中)
若以1点为dfs起点可以求出包含1的强连通分量 但不能在搜索完以2点为根节点的搜索树时判断2是否是一个强连通分量的根节点
接下来正式开始介绍Tarjan算法:
Tarjan算法基于dfs
强连通分量在dfs中的根节点延伸的搜索树中包含所有与根节点强连通的点(废话)
强连通分量是由环构成(废话*2)
那么一个点V是一个强连通分量的根节点的条件是在它的搜索树中没有节点能访问到它的父节点或祖先 否则V可与它的父亲或祖先节点构成一个环故与V强连通的点的集合属于与V的父亲或祖父节点强连通的点的集合 同时点V若与它的祖父节点或父节点相连 那么它的祖父或父亲节点所在强连通分量的根节点显然与点V所在的强连通分量的根节点相同
再然后在dfs搜索的过程中搜索与回溯的过程相当于一个栈而子节点在栈中永远在父节点的上方 那么一个强连通分量的根节点在栈中时也必然在与它所有强连通的点的下方 而平时回溯时会直接退栈而我们在回溯时判断此时的节点是不是强连通分量的根节点 是 将当前点和在当前点之上的所有点取出 这些点共同构成一个强连通分量 不是 则保留栈中节点
因为一个节点若不是强连通分量的根节点 那由它搜索下去必定与栈中的某个节点V'之间所有的节点构成一个环而环上所有点之间强连通 又因为强连通分量的根节点在栈中必然在与它所有强连通的点下方故V'便是此时这个节点所在强连通分量的根节点 而且由以上操作可知留在栈中的点属于某个以栈中某个点为根节点的强连通分量 同时由dfs特性知回溯到某个强连通分量的根节点时栈中在它之上的点不可能属于此根节点之下的强连通分量否则说明该节点不是根节点因为它的子节点可以与父节点或祖先节点相连
具体代码实现时可以维护一个Low[V] Low[V]记录的是V所属于的强连通分量的根节点的dfs序 由dfs序可知强连通分量的根节点的dfs序是整个强连通分量中最小的 那么搜索完后只需要判断Low[V]是否等于V的dfs序即可知V是否为强连通分量的根节点 而显然Low[V]=min(Low[to],Low[V]),to∈V的子节点 而当V连接的是已经在栈中的点V'时则Low[V]=min(Low[V],V'的dfs序)
算法时间复杂度:
显然Tarjan算法中每一点都只会进栈一次出栈一次 而每一个节点都会遍历它的所有边 故Tarjan算法求有限图中的强连通分量的时间复杂度为T(n+m)
代码以后补齐:
Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量的更多相关文章
- 图论-求有向图的强连通分量(Kosaraju算法)
求有向图的强连通分量 Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序 ...
- Tarjan算法 求 有向图的强连通分量
百度百科 https://baike.baidu.com/item/tarjan%E7%AE%97%E6%B3%95/10687825?fr=aladdin 参考博文 http://blog.csdn ...
- Tarjan算法求有向图的强连通分量
算法描述 tarjan算法思想:从一个点开始,进行深度优先遍历,同时记录到达该点的时间(dfn记录到达i点的时间),和该点能直接或间接到达的点中的最早的时间(low[i]记录这个值,其中low的初始值 ...
- tarjan算法(割点/割边/点连通分量/边连通分量/强连通分量)
tarjan算法是在dfs生成一颗dfs树的时候按照访问顺序的先后,为每个结点分配一个时间戳,然后再用low[u]表示结点能访问到的最小时间戳 以上的各种应用都是在此拓展而来的. 割点:如果一个图去掉 ...
- (转)求有向图的强连通分量个数(kosaraju算法)
有向图的连通分量的求解思路 kosaraju算法 逛了很多博客,感觉都很难懂,终于找到一篇能看懂的,摘要记录一下 原博客https://www.cnblogs.com/nullzx/p/6437926 ...
- 【数据结构】DFS求有向图的强连通分量
用十字链表结构写的,根据数据结构书上的描述和自己的理解实现.但理解的不透彻,所以不知道有没有错误.但实验了几个都ok. #include <iostream> #include <v ...
- 求有向图的强连通分量个数 之 Kosaraju算法
代码: #include<cstdio> #include<cstring> #include<iostream> using namespace std; ][] ...
- Tarjan算法初探(2):缩点
接上一节 Tarjan算法初探(1):Tarjan如何求有向图的强连通分量 Tarjan算法一个非常重要的应用就是 在一张题目性质在点上性质能够合并的普通有向图中将整个强连通分量视作一个点来把整张图变 ...
- 图->连通性->有向图的强连通分量
文字描述 有向图强连通分量的定义:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly co ...
随机推荐
- python匿名函数 高阶函数 内置函数 文件操作
1.匿名函数 匿名就是没有名字 def func(x,y,z=1): return x+y+z 匿名 lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用 ...
- SSH入门常用命令
一.参考链接大猫的博客
- 使用ember-cli脚手架快速构建项目
步骤: 安装Ember. 创建一个新应用程序. 定义路由. 编写一个UI组件. 构建您的应用程序以部署到生产环境. 安装Ember 您可以使用npm(Node.js包管理器,你需要安装node.js) ...
- 6.Spring MVC SSM整合问题总结
1.Cannot find class [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter] for ...
- Linux history命令详解
history命令用于显示指定数目的指令命令,读取历史命令文件中的目录到历史命令缓冲区和将历史命令缓冲区中的目录写入命令文件. 该命令单独使用时,仅显示历史命令,在命令行中,可以使用符号!执行指定 ...
- java 规范
https://blog.csdn.net/mengxiangsun/article/details/79020226
- 一、BOM 二、DOM
一.BOM(window对象)###<1>window属性对象 window.location 当前浏览器的地址对象 window.history 浏览器访问过的地址对象 window.o ...
- 使用github客户端上传文件(瓜皮教程)
因为栋哥的课才接触道github这个东西,离第一次接触大概有一年左右了吧,记得不是太清楚了,但是,直到前几天前我还是不知道如何配置,利用git上传文件,之前也是叫同学帮忙弄得,但是这次软工实践要频繁用 ...
- Leetcode Weekly Contest 86
Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个 ...
- JSF标签之f:facet 的用法
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zkn_CS_DN_2013/article/details/33717091 f:facet标签用来 ...