Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点
前言
\(Tarjan\)是一个著名的将强连通分量缩点的算法。
大致思路
它的大致思路就是在图上每个联通块中任意选一个点开始进行\(Tarjan\)操作(依据:强连通分量中的点可以两两到达,因此从任意一个点开始都没关系)。
具体实现
对于每一个点,先记录它的\(dfs\)序,并将该点加入一个栈中,并标记其在栈中,然后用\(low[]\)数组来记录从它出发能到达的字典序最小的节点。
枚举它所能到达的每一个节点,并对每一个节点进行分类讨论:
设当前节点为\(x\),枚举到的节点为\(son\)。
如果\(son\)没有被访问过,就先对它进行Tarjan操作,然后更新\(low[x]\)(\(low[x]=min(low[x],low[son])\))。
如果\(son\)已经被访问过,又分两种情况:
如果\(son\)在栈中,那么更新\(low[x]\)。
如果\(son\)不在栈中,那么代表已经对\(son\)所能到达的每一个节点操作过,说明从\(son\)不能到达\(x\),即它们不在同一个强连通分量中,因此不能更新\(low[x]\)。
在枚举完每一个节点后,我们可以判断当前节点是否就是它能到达的dfs序最小的节点,如果是的话,说明它是一个强连通分量中最早被访问过的(当然,也有可能说明它所在的强连通分量中就只有它一个节点),否则,就说明还有比它更早被访问过的,那么退出函数。
如果当前节点是一个强连通分量中最早被访问到的,那么就说明栈中在它上面的节点全都和它在一个强连通分量中,我们可以新建一个强连通分量,并将它连同在它上面的点全部加入这个强连通分量中即可(加入的同时要注意更新这个强连通分量的信息,可参考例题)。
代码
inline void Tarjan(int x)//x是当前访问到的节点
{
dfn[x]=low[x]=++d,Stack[++top]=x,vis[x]=1;//记录当前节点的dfs序与当前节点所能到达的dfs序最小的点,将当前节点加入栈中,并标记当前节点在栈中
for(register int i=lnk[x];i;i=e[i].nxt)//枚举从当前节点出发的每一条边
{
if(!dfn[e[i].to]) Tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);//如果这个节点没访问过,就先对这个节点进行操作,然后更新当前节点能到达的dfs序最小的点
else if(vis[e[i].to]) low[x]=min(low[x],low[e[i].to]);//否则,如果这个点在栈中,就进行更新
}
if(low[x]==dfn[x])//如果当前节点就是当前节点能到达的dfs序最小的点,则对当前强连通分量进行缩点
{
a[x].col=++cnt,vis[x]=0;//给当前节点加入一个新的强连通分量,并标记当前节点已出栈(如果需要,还要初始化这个强连通分量的信息,可参考例题)
while(Stack[top]^x) a[Stack[top]].col=cnt,vis[Stack[top--]]=0;//将栈中当前节点之上的节点一一弹出(如果需要,还要同时更新这个强连通分量的信息)
--top;//将当前节点弹出
}
}
例题
例题1:【洛谷2403】[SDOI2010] 所驼门王的宝藏
例题2:【51nod1815】调查任务
Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点的更多相关文章
- tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)
这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...
- 1051: [HAOI2006]受欢迎的牛 (tarjan强连通分量+缩点)
题目大意:CodeVs2822的简单版本 传送门 $Tarjan$强连通分量+缩点,若连通块的个数等于一则输出n:若缩点后图中出度为0的点个数为1,输出对应连通块内的点数:否则输出0: 代码中注释部分 ...
- Tarjan在图论中的应用(三)——用Tarjan来求解2-SAT
前言 \(2-SAT\)的解法不止一种(例如暴搜?),但最高效的应该还是\(Tarjan\). 说来其实我早就写过用\(Tarjan\)求解\(2-SAT\)的题目了(就是这道题:[2019.8.14 ...
- tarjan求强连通分量+缩点+割点以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- Tarjan求强连通分量 缩点
强连通分量的定义: 在一张有向图中,如果两个点u,v之间能相互到达则称这两个点u,v是强连通的,在这个基础上如果有向图G中的任意两个顶点都强连通,那么称图G是一个强连通图.有向非强连通图的极大强连通子 ...
- tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- HDU 1827 Summer Holiday(tarjan求强连通分量+缩点构成新图+统计入度+一点贪心思)经典缩点入门题
Summer Holiday Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)
UVA1327 King's Quest POJ1904 King's Quest 题意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚.现有一个匹配表,将每个王子都与一个自己 ...
- 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点
Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...
随机推荐
- 51nod1049(最大子段和2)
题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1049 题意:中文题诶- 思路:本题和51nod1049(题解 ...
- poj 1635 Subway tree systems(树的最小表示)
Subway tree systems POJ - 1635 题目大意:给出两串含有‘1’和‘0’的字符串,0表示向下搜索,1表示回溯,这样深搜一颗树,深搜完之后问这两棵树是不是同一棵树 /* 在po ...
- Mysql缓存的配置和使用
在mysql服务器高负载的情况下,必须采取一种措施给服务器减轻压力,减少服务器的I/O操作.一般采用的方法是优化sql操作语句,优化服务器的配置参数,从而提高服务器的性能.Mysql使用了几种内存缓存 ...
- MCP|MZL|Accurate Estimation of Context- Dependent False Discovery Rates in Top- Down Proteomics 在自顶向下蛋白组学中精确设定评估条件估计假阳性
一. 概述: 自顶向下的蛋白质组学技术近年来也发展成为高通量蛋白定性定量手段.该技术可以在一次的实验中定性上千种蛋白,然而缺乏一个可靠的假阳性控制方法阻碍了该技术的发展.在大规模流程化的假阳性控制手段 ...
- Docker Flie
七.Docker File .dockeringore:打包忽略的文件列表,每行写一个文件的路径,可使用通配符 FROM指令:指定基础镜像 FROM <repository>[:<t ...
- JS滑动下划线导航菜单实现原理
效果如下:http://campus.51job.com/test/zengxl/js html: <div class="mainnav"> <div clas ...
- linux别名防删除
最近有不相信rm -rf 了,虽然恢复了但是很难受啊 加个别名吧, 1.查看系统别名配置 alias 2.配置别名(临时生效) alias rm='echo do not use rm command ...
- POJ - 3450
题目链接:http://poj.org/problem?id=3450 Corporate Identity Time Limit: 3000MS Memory Limit: 65536K Tot ...
- Codeforces Round #172 (Div. 2) D. Maximum Xor Secondary 单调栈应用
http://codeforces.com/contest/281/problem/D 要求找出一个区间,使得区间内第一大的数和第二大的数异或值最大. 首先维护一个单调递减的栈,对于每个新元素a[i] ...
- 网络编程——TCP协议
1.TCP程序概述 TCP是一个可靠的协议,面向连接的协议. 实现TCP程序,需要编写服务器和客户端,Java API为我们提供了java.net包,为实现网络应用程序提供类. ServerSocke ...