ACM(图论)——tarjan算法详解
---恢复内容开始---
tarjan算法介绍:
一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法。通过变形,其亦可以求解无向图问题
桥:
割点:
连通分量:
适用问题:
求解(有向图/无向图)的,桥,割点,环,回路等问题
整体思想:
如果我们欲要求解,桥的个数,割点的个数,环的数目,归根结底,是分析清楚一个图 有几个 环,每个环包含哪些节点,那些边。
而 tarjan算法就是做的这件事情,通过dfs遍历每一条边和节点,算出有几个环,每个环中有哪些节点。那么是如何做的呢,整体上我们可以这么理解。
首先定义两个 数组 dfn[i] low[i] 分别代表 每个节点的代号 和 每个环的代号,还有一个分析的次序 cnt变量。然后我们用dfs 深度遍历每一个顶点,每遍历一个节点 cnt++,low[i]=dfn[i]=cnt 就是说,每个节
点的代号代表它是第几个被我们分析的,同时low[i]=cnt 是说刚开始我们无法判断哪些节点能组成环,所以就初始化为每个节点自己是一个环,这个环的代号就是自己的代号。而当我们分析到一定程度后
发现,某些节点能组成一个环,再回溯,将这几个节点所属环代号改为一个统一的环代号。到最后,如果一个节点的环代号和自己的代号相等,说明他是一个割点,而如果不相等,则这个节点属于一个
环,并且通过环代号知道他是那个环。
思想详细分解:

这里我们需要对一些变量重新定义其在代码中的含义,之前所说只是理解上的含义。
dfn[i]:节点 i dfs的次序
low[i]: 节点 i 所在环中 所有节点中最小的 dfn[i]。
vis[i]:这个节点是否被遍历过,遍历过为1,否则为0
cnt:遍历次数
a[60]:用来存储图的 vector。
-------------------------------------------------------------------------------------------------详细的分步分析------------------------------------------------------------------------------------------------------------------------------------------------------
假如我们从 节点1 开始遍历, low[1]=dfn[1]=cnt=1; 然后遍历他的下一个节点,如果下一个节点曾经遍历过,说明这里能形成一个环,如果没便利过,就接着往下遍历。下一个是 节点2
low[2]=dfn[2]=cnt=2; 再下一个是 节点3 low[3]=dfn[3]=cnt=3 , 然后 low[4]=dfn[4]=cnt =4,直到 4 的下一个节点可以到 节点2 曾经便利过 ,因此节点2到节点4之间会有一个环,接着我们向后回溯
使 low[4]=min(low[4],low[2])=2 low[3]=min(low[3],low[4])=2 low[2]=min(low[2],low[3])=2 low[1]=min(low[1],low[2])=1, 我们就会发现 节点2 ,节点3 ,节点4,的low与dfn就不一样了,且low都等于2,说明
他们三个组成了一个环,然后接着向下遍历 节点5 ,没有被遍历过,所以low[5]=dfn[5]=cnt=5;
至此 整体上 low[2]=low[3]=low[4]=2 low[1]=dfn[1]=1 low[5]=dfn[5]=5; 所以,这个图中有那几个群 ,群里有哪些节点,有哪些是割点,桥等 都一目了然了。
下面是详细的代码
求一个无向图的所有桥的个数,先输入两个数 n个节点,m条边。再输入 m对 数代表边的两个节点。
代码示例:
#include <bits/stdc++.h> using namespace std;
vector<int> a[];
int dfn[];
int low[];int vis[];
int cnt=;
int dig=;
//这里是tarjan代码模板核心
void tarjan(int w,int u){
vis[u]=;
low[u]=dfn[u]=(cnt++);
for(int i=;i<a[u].size();i++){
int v = a[u][i];
if(v==w) continue;//因为是无向图,防止向后返回去遍历
if(vis[v]!=) tarjan(u,v);//没有便利过,就接着向下遍历,直到找到后,再执行下面的代码,也就是回溯。
if(vis[v]==) low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u]){
dig++;
}
}
void init(){
//初始化函数
memset(dfn,,sizeof dfn);
memset(low,,sizeof low);
memset(vis,,sizeof vis);
memset(sp,,sizeof sp);
}
int main()
{
int n,m;
cin>>n>>m;
init();
for(int i=;i<m;i++){
int k1,k2;
cin>>k1>>k2;
a[k1].push_back(k2);
a[k2].push_back(k1);
}
tarjan(,);
cout<<dig-<<endl;
return ;
}
---恢复内容结束---
ACM(图论)——tarjan算法详解的更多相关文章
- Tarjan算法详解
Tarjan算法详解 今天偶然发现了这个算法,看了好久,终于明白了一些表层的知识....在这里和大家分享一下... Tarjan算法是一个求解极大强联通子图的算法,相信这些东西大家都在网络上百度过了, ...
- Tarjan 算法详解
一个神奇的算法,求最大连通分量用O(n)的时间复杂度,真实令人不可思议. 废话少说,先上题目 题目描述: 给出一个有向图G,求G连通分量的个数和最大连通分量. 输入: n,m,表示G有n个点,m条边 ...
- Tarjan算法详解理解集合
[功能] Tarjan算法的用途之一是,求一个有向图G=(V,E)里极大强连通分量.强连通分量是指有向图G里顶点间能互相到达的子图.而如果一个强连通分量已经没有被其它强通分量完全包含的话,那么这个强连 ...
- Tarjan算法 详解+心得
Tarjan算法是由Robert Tarjan(罗伯特·塔扬,不知有几位大神读对过这个名字) 发明的求有向图中强连通分量的算法. 预备知识:有向图,强连通. 有向图:由有向边的构成的图.需要注意的是这 ...
- KM算法详解[转]
KM算法详解 原帖链接:http://www.cnblogs.com/zpfbuaa/p/7218607.html#_label0 阅读目录 二分图博客推荐 匈牙利算法步骤 匈牙利算法博客推荐 KM算 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- 机器学习经典算法详解及Python实现--基于SMO的SVM分类器
原文:http://blog.csdn.net/suipingsp/article/details/41645779 支持向量机基本上是最好的有监督学习算法,因其英文名为support vector ...
- [转] KMP算法详解
转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的K ...
随机推荐
- 蒙特卡洛树,AMAF,Rave浅析
蒙特卡洛树搜索: MCTS使用蒙特卡洛模拟来估计每个节点的价值. 其默认策略为贪婪算法, 即每次选择价值最高的节点进行模拟, 在每次模拟得到结果后, 将结果反馈回每个上级节点, 更新节点价值. 通常来 ...
- rest_famework 增删改查初第二阶段(中级,此阶段是优化初级阶段的代码)的使用
url: re_path('authors/$', views.AuthorView.as_view()),re_path('authors/(\d+)/$', views.AuthorDetailV ...
- if __name__ == 'main': 的作用和原理
if __name__ == 'main': 功能 一个python的文件有两种使用的方法,第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行. if __na ...
- jsfl 进入影片 退出影片
targetMC=fl.getDocumentDOM().getTimeline().layers [0].frames[0].elements[0]; fl.getDocumentDOM().lib ...
- NSIS 查找目录下的所有文件夹
在制作安装包的时候,需要查看下某一目录下的所有文件夹的名称.经过查资料发现需要用到NSIS 的一个插件Locate.下载该插件后,会在NSIS的安装目录 ...Program Files\NSIS\P ...
- css note
1.text-align规定了其子元素的对齐方式,当设置在子元素无效时,尝试设置在父元素,子元素可以水平居中: 2.vertical-align使用的前提,首先元素必须是display:inline ...
- docker使用flannel网络
基础环境我们使用了两台centos 7系统 基础配置为: 两台机器IP为 172.17.3.10 172.17.3.62 hosts文件配置为 172.17.3.10 node1 172.17.3.6 ...
- Visual Studio 2017 密匙
趁着这两天微软发布了Visual Studio 2017,安装体验了这个史上最强IDE最新版,分享一下自己的安装过程: VS2017下载地址,该版本堪称史上最大IDE,随便勾了几个选项,就要占用几十个 ...
- (英文版)VScode一键生成.vue模板
1. 安装vscode,官网地址 2.安装一个插件,识别vue文件 插件库中搜索Vetur,下图中的第一个,点击安装(Install) 3.新建代码片段 点击Code(代码)-Preferences( ...
- GIS 案例教程-蜂窝多边形制作模型
GIS 案例教程-蜂窝多边形制作模型 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 优点: 拖放式,非编程,复制即用,不用配置. 效率高,非迭代,可以处理大数据. ...