强连通分量——tarjan算法
概念:
有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。
注:强联通分量仅仅是对有向图来说。
代码模板:
void tarjan(int x)
{
cnt++;
dfn[x] = low[x] =cnt;
q.push(x);
insta[x] =true;
for(int i=head[x];i;i=edge[i].next )
{
int u =edge[i].to;
if(!dfn[u])
{
tarjan(u);
low[x] = min(low[x],low[u]);
}else if(insta[u])
{
low[x] = min(low[x],dfn[u]);
}
}
int k;
if(low[x] == dfn[x])
{
num++;
do{
k =q.top();
q.pop();
insta[k] = false;
id[k] = num;
}while(k!=x);
}
}
算法理解:
tarjan算法是一种基于DFS的算法,并且运用了数据结构栈。
此算法需要两个关键的数组:low[ ] 和 dfn[ ].
在我的理解看来:dfn[ ]数组是用来储存时间戳的,及何时访问到此节点。因此在每次对一个点进行DFS后,自己就形成了一个独一无二的时间戳,且永远不会改变。所以常一句dfn的值来判断是否需要进一步的深搜。
low[ ]数组用来储存与此节点相联通的节点的最小下标。因此low[ ]值相等的点在同一个强联通分量。
首先这个图不一定是一个连通图,所以跑Tarjan时要枚举每个点,若dfn[ ] == 0,进行深搜。进入深搜后,判断此点邻接点,如果邻接点的dfn[ ]为0,证明还没有访问过,就对此邻接点进行深搜,若dfn[ ]不为零,则判断此邻接点是否在栈中,若已经在栈中,则此时证明已经构成了环,则更新low[ ],与邻接点的时间戳进行比较,取最小值,例如下面这种情况:

当对点5进行邻边搜索的时候,仅仅发现了点1,并且点1此时在栈中,这样,就构成了一个环。
在不断的深搜的过程中如果没有路可走了(已经没有出边了),那么就进行回溯,回溯时不断比较low[ ], 取最小的low[ ]值。
如果dfn[x]==low[x],则此时x可以看作是强联通分量的根,就对栈进行弹出操作,直到x被弹出。
手动模拟一下过程:

从1进入:dfn[1] =low[1] =++cnt = 1
入栈1: 1
从1进入2:dfn[2] = low[2] = ++cnt =2
入栈2: 12
从2进入3: dfn[3]=low[3] =++cnt =3;
入栈3: 123
从3进入4: dfn[4] = low[4] = ++cnt =4;
入栈4:1234;
4无出度,之后判断dfn[4] == low[4];
4及4之前的点全部弹出
并且id[4] = ++num=1;
栈:123
并回溯到3
对low[3] = min(low[4],low[3])=3;
之后判断low[3] == dfn[3] =3;3及3以后的点弹出
id[3] = ++num=2;
栈:12;
继续回溯到2,对low[2] = min(low[2],low[3])=2;
从2 进入到5,dfn[5]=low[5] = ++cnt =5;
入栈5:125
从5进入1,由于1已经在栈中,则更新low[5] =min(low[5],dfn[1]) =1;
回溯到2,更新low[2 ] =min(low[2],low[5]) =1;
回溯到1,更新low[1] =min(low[1],low[2])=low[1] =1;
从1进入6,dfn[6] =low[6] = 6;
入栈6:1256
由于临点5已经在栈中,更新low[6] = min(low[6],low[5]) = 1;
回溯到1,由于low[1] ==dfn[1],则弹出1及一以上的点:
id[1] = id[2] =id[5] = id[6] = ++num = 3;
至此,强联通分量全部找出;
以上;
强连通分量——tarjan算法的更多相关文章
- 有向图强连通分量Tarjan算法
在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间 ...
- 有向图强连通分量 Tarjan算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- [有向图的强连通分量][Tarjan算法]
https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的 ...
- 图之强连通、强连通图、强连通分量 Tarjan算法
原文地址:https://blog.csdn.net/qq_16234613/article/details/77431043 一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶 ...
- 图论-强连通分量-Tarjan算法
有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...
- 求图的强连通分量--tarjan算法
一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...
- POJ1236_A - Network of Schools _强连通分量::Tarjan算法
Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are connected to a compute ...
- poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】
题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Sub ...
- 强连通分量--tarjan算法
今天学了一个强连通分量,用tarjan做.北京之前讲过,今天讲完和之前一样,没有什么进步.上课没听讲,只好回来搞,这里安利一个博客:链接 https://blog.csdn.net/qq_343746 ...
随机推荐
- Collection 的子类 List
List集合的一些使用方法: 一. 声明集合: List<String> list = new ArrayList<String>(); 二.往集合里面添加元素 list.ad ...
- JPA或Hibernate中使用原生SQL实现分页查询、排序
发生背景:前端展示的数据需要来自A表和D表拼接,A表和D表根据A表的主键进行关联,D表的非主键字段关联C表的主键,根据条件筛选出符合的数据,并且根据A表的主键关联B表的主键(多主键)的条件,过滤A表中 ...
- ArcEngine语法笔记(VB)
1.获取图层字段 Dim pTable As ITable = pLayer Dim pField As IField pField = pTable.Fields.Field(i) Next 2. ...
- 代码注释规范-IDEA 配置 Java 类方法注释模板
1. 引言 团队开发时,业务模块分配的越清晰,代码注释管理越完善,越有利于后面维护,后面再管理也方便不少.另外也起着"文字砖"的作用,你懂的.注释不需要很详细,把代码块方法 ...
- 通过自己实现接口来加深理解SpringMVC的执行流程
功能介绍 上篇文章[从源码角度了解SpringMVC的执行流程]通过接口源码向大家介绍了SpringMVC的执行流程,主要偏重于源码.这篇文件我们来自己实现那几个关键接口,来真实体验下SpringMV ...
- SpringCloud组件和概念介绍(一)
一:什么是微服务(Microservice) 微服务英文名称Microservice,Microservice架构模式就是将整个Web应用组织为一系列小的Web服务.这些小的Web服务可以独立地编译及 ...
- Activiti服务任务(serviceTask)
Activiti服务任务(serviceTask) 作者:Jesai 都有一段沉默的时间,等待厚积薄发 应用场景: 当客户有这么一个需求:下一个任务我需要自动执行一些操作,并且这个节点不需要任何的人工 ...
- render()到底渲染的什么?
1.格式 render(request,"xx.html",{"xx": xx}) 2.本质 通过模板语言动态渲染字符串(HTML文件) 注意: 1.HTML文 ...
- 解决浮点运算精度不准确,BigDecimal 加减乘除
package com.kflh.boxApi.utils.util; import java.math.BigDecimal; /** * @program: BoxApi * @descripti ...
- BZOJ 3513 idiots
题目传送门 分析: FFT一手统计两根棍子相加的方案 然后一个值2S可能会被同一根S自己乘自己得到 然后要减去 其次,A+B和B+A会被算成两种方案,所以还要除以2 然后不太好算合法的方案数,但是非法 ...