tarjan求强连通分量模板
什么是强连通分量?
百度百科
有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。
实际上构成一个环的节点都可以叫做强连通分量,特别的单独的一个节点也可以叫做强连通分量
怎么实现tarjan?
tarjan算法中的数组
dfn(遍历的编号数组) low(遍历的最小的父节点) vis(记录数组) color(染色数组) stack(栈)
具体做法(dfs)
①把节点放入栈并且初始化dfn和low相等等于当前的节点,使vis记录这个节点
②遍历当前节点的临近节点并判断
(1)如果这个节点并没有被遍历过,dfs这个节点在回溯的时候设置求low数组
公式:low[n]=min(low[n],low[p])其中n是传入的形参,p是临近的节点
(2)如果这个节点被遍历过了,但是还没来得及入栈,那么计算一下low数组
③染色
(1)如果最终一个节点的dfn和low是一样的话,那么说明这个节点可以成为是一个强连通的头节点
(2)去除栈帧,把每个头结点上的栈都染成相同的颜色。
(3)注意这个时候需要去除vis标记
(4)注意如果栈到了n这个节点也得把这个节点提出栈才可以
代码
#include <bits/stdc++.h>
using namespace std;
map<int,int> dfn,low,vis,color;
stack<int> st;
int sum,col;
vector<int> G[1005];
void tarjan(int n)
{
dfn[n]=low[n]=++sum;
vis[n]=1;
st.push(n);
for(int i=0;i<G[n].size();i++)
{
int p=G[n][i];
if(!dfn[p])
{
tarjan(p);
low[n]=min(low[n],low[p]);
}
else if(vis[p])
low[n]=min(low[n],low[p]);
}
if(low[n]==dfn[n])
{
color[n]=++col;
vis[n]=0;
while(st.top()!=n)
{
color[st.top()]=col;
vis[st.top()]=0;
st.pop();
}
st.pop();
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,m;
cin>>n>>m;
while(m--)
{
int t1,t2;
cin>>t1>>t2;
G[t1].push_back(t2);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=1;i<=n;i++)
cout<<color[i]<<" ";
}
tarjan求强连通分量模板的更多相关文章
- Tarjan求强连通分量、求桥和割点模板
Tarjan 求强连通分量模板.参考博客 #include<stdio.h> #include<stack> #include<algorithm> using n ...
- tarjan求强连通分量(模板)
https://www.luogu.org/problem/P2341 #include<cstdio> #include<cstring> #include<algor ...
- tarjan求强连通分量+缩点+割点以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- tarjan求强连通分量+缩点+割点/割桥(点双/边双)以及一些证明
“tarjan陪伴强联通分量 生成树完成后思路才闪光 欧拉跑过的七桥古塘 让你 心驰神往”----<膜你抄> 自从听完这首歌,我就对tarjan开始心驰神往了,不过由于之前水平不足,一 ...
- UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】
Road Networks Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Stat ...
- UESTC 901 方老师抢银行 --Tarjan求强连通分量
思路:如果出现了一个强连通分量,那么走到这个点时一定会在强连通分量里的点全部走一遍,这样才能更大.所以我们首先用Tarjan跑一遍求出所有强连通分量,然后将强连通分量缩成点(用到栈)然后就变成了一个D ...
- Tarjan求强连通分量,缩点,割点
Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...
- HDU 1827 Summer Holiday(tarjan求强连通分量+缩点构成新图+统计入度+一点贪心思)经典缩点入门题
Summer Holiday Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- CCF 高速公路 tarjan求强连通分量
问题描述 某国有n个城市,为了使得城市间的交通更便利,该国国王打算在城市之间修一些高速公路,由于经费限制,国王打算第一阶段先在部分城市之间修一些单向的高速公路. 现在,大臣们帮国王拟了一个修高速公路的 ...
随机推荐
- SemaphoreSlim
https://msdn.microsoft.com/en-us/library/system.threading.semaphoreslim(v=vs.110).aspx Represents a ...
- hdoj--2186--悼念512汶川大地震遇难同胞——一定要记住我爱你(模拟水题)
悼念512汶川大地震遇难同胞--一定要记住我爱你 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- 【POJ 1804】 Brainman
[题目链接] 点击打开链接 [算法] 本题是一个很经典的问题 : 归并排序求逆序对数,可以用分治算法解决 分治,分而治之,分治算法的思想就是将一个问题转化为若干个子问题,对这些子问题分别求解,最后, ...
- bzoj1047
二维单调队列 rmq很明显会超时,如果这个序列是一维的,很明显就是个单调队列,现在就是把一维的单调队列转换为二维单调队列. 先求出每一列的窗口极值,然后对于每一行做单调队列,值就是之前求出每个位置结尾 ...
- 【转载】存储的一些基本概念(HBA,LUN)
1.关于HBA HBA的全称为Host Bus Adapter,即主机总线适配器. a.总线适配器是个什么东西呢? 我们首先要了解一下主机的结构,一台计算机内部多半由两条总线串在起来(当然实际情况会 ...
- 微信小程序获取自定义属性值
写小程序的时候用到了自定义属性,特地来记录一下 特别是这个坑,必须得说一说 wxml <view class='box' bindtap='getValue'> <view clas ...
- 洛谷 P1037 产生数
题目描述 给出一个整数n(n<10^30)和k个变换规则(k≤15). 规则: 一位数可变换成另一个一位数: 规则的右部不能为零. 例如:n=234.有规则(k=2): 2->53-> ...
- 贪心 HDOJ 5355 Cake
好的,数据加强了,wa了 题目传送门 /* 题意:1到n分成m组,每组和相等 贪心:先判断明显不符合的情况,否则肯定有解(可能数据弱?).贪心的思路是按照当前的最大值来取 如果最大值大于所需要的数字, ...
- DFS BestCoder Round #49 ($) 1001 Untitled
题目传送门 /* DFS:从大到小取模,因为对比自己大的数取模没意义,可以剪枝.但是我从小到大也过了,可能没啥大数据 */ /************************************* ...
- Node“getTextContent() is undefined for the type Node”处理办法
最近一个项目在MyEclipse导入后总是报getTextContent() is undefined for the type Node错误. 经过查找原来是因为Node类为JDK中自带的(org. ...