图的Tarjan算法
“Tarjan有三种算法 你们知道吗”——Tar乙己
void tarjan(int x)
{
low[x]=dfn[x]=++ind;
q[++top]=x;mark[x]=;
for(int i=last[x];i;i=e[i].next)
if(!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
}
else if(mark[e[i].to])
low[x]=min(low[x],dfn[e[i].to]);
if(low[x]==dfn[x])
{
int now=;scc++;
while(now!=x)
{
now=q[top--];mark[now]=;
bl[now]=scc;num[scc]++;
}
}
}
缩点
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=;
int first[maxn],to[maxn],next[maxn],cnt,from[maxn];
void add(int u,int v)
{
from[++cnt]=u;
to[cnt]=v;
next[cnt]=first[u];
first[u]=cnt;
}
int dfn[maxn],low[maxn],vis[maxn],ind,scc,now,st[maxn],top;
int isc[maxn];
vector<int> bl[maxn];
int blc;
int tag[maxn];
void Tarjan_dfs(int x,int fa)
{
int son=;
low[x]=dfn[x]=++ind;
for(int i=first[x];i;i=next[i])
{
int now=to[i];
if(!dfn[now])
{
st[++top]=i;son++;
Tarjan_dfs(now,x);
low[x]=min(low[x],low[now]);
if(low[now]>=dfn[x])
{
isc[x]=;
bl[++blc].clear();
while()
{
int num=st[top--];
if(tag[from[num]]!=blc)
{
bl[blc].push_back(from[num]);
tag[from[num]]=blc;
}
if(tag[to[num]]!=blc)
{
bl[blc].push_back(to[num]);
tag[to[num]]=blc;
}
if(to[num]==now && from[num]==x)break;
}
}
}
else if(dfn[now]<dfn[x] && now!=fa)
{
st[++top]=i;
low[x]=min(low[x],dfn[now]);
}
}
if(fa== && son==)isc[x]=;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=;i<=n;i++)if(!dfn[i])Tarjan_dfs(i,-);
cout<<blc<<endl;
return ;
}
点双连通分量
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<vector>
using namespace std;
const int maxn=;
int first[maxn],to[maxn],next[maxn],cnt,from[maxn];
void add(int u,int v)
{
from[++cnt]=u;
to[cnt]=v;
next[cnt]=first[u];
first[u]=cnt;
}
int dfn[maxn],low[maxn],vis[maxn],ind,scc,now,st[maxn],top;
int isb[maxn];
vector<int> bl[maxn];
int blc;
int tag[maxn];
void Tarjan_dfs(int x,int fa)
{
dfn[x]=low[x]=++ind;
for(int i=first[x];i;i=next[i])
{
int v=to[i];
if(!dfn[v])
{
Tarjan_dfs(v,x);
low[x]=min(low[x],low[v]);
if(low[v]>dfn[x])
isb[i]=isb[i^]=;
}
else if(dfn[v]<dfn[x] && v!=fa)low[x]=min(low[x],dfn[v]);
}
}
int vis[maxn];
void dfs(int x)
{
vis[x]=;
tag[x]=blc;
for(int i=first[x];i;i=next[i])
{
int v=to[i];
if(isb[v])continue;
if(!vis[i])dfs(v);
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=;i<=n;i++)if(!dfn[i])Tarjan_dfs(i,-);
for(int i=;i<=n;i++)if(!vis[i]){blc++;dfs(i);}
cout<<blc<<endl;
return ;
}
边双连通分量
图的Tarjan算法的更多相关文章
- tarjan算法 POJ3177-Redundant Paths
参考资料传送门 http://blog.csdn.net/lyy289065406/article/details/6762370 http://blog.csdn.net/lyy289065406/ ...
- #图# #SPFA# #Tarjan# ----- BZOJ1179
SPFA算法 SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法. 判负环(在差分约束系统中会得以体现).如果某个点进入队列的次数超过N ...
- Tarjan算法:求解图的割点与桥(割边)
简介: 割边和割点的定义仅限于无向图中.我们可以通过定义以蛮力方式求解出无向图的所有割点和割边,但这样的求解方式效率低.Tarjan提出了一种快速求解的方式,通过一次DFS就求解出图中所有的割点和割边 ...
- 图之强连通、强连通图、强连通分量 Tarjan算法
原文地址:https://blog.csdn.net/qq_16234613/article/details/77431043 一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶 ...
- 【强联通图 | 强联通分量】HDU 1269 迷宫城堡 【Kosaraju或Tarjan算法】
为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明 ...
- Tarjan算法:求解无向连通图图的割点(关节点)与桥(割边)
1. 割点与连通度 在无向连通图中,删除一个顶点v及其相连的边后,原图从一个连通分量变成了两个或多个连通分量,则称顶点v为割点,同时也称关节点(Articulation Point).一个没有关节点的 ...
- 图之强连通--Tarjan算法
强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components ...
- 图的连通性——Tarjan算法&割边&割点
tarjan算法 原理: 我们考虑 DFS 搜索树与强连通分量之间的关系. 如果结点 是某个强连通分量在搜索树中遇到的第⼀个结点,那么这个强连通分量的其余结点肯定 是在搜索树中以 为根的⼦树中. 被称 ...
- 图的连通性--Tarjan算法
一些概念 无向图: 连通图:在无向图中,任意两点都直接或间接连通,则称该图为连通图.(或者说:任意两点之间都存在可到达的路径) 连通分量: G的 最大连通子图 称为G的连通分量. 有向图 (ps.区别 ...
随机推荐
- python 文字识别 之 pytesseract
pytesseract资源 链接:https://pan.baidu.com/s/1eTsqhsY 密码:j0yo 安装时前面一直next就可以了,直到这一步,勾选Math和Chinese,支持计算和 ...
- poj 2524 Ubiquitous Religions(并查集)
Ubiquitous Religions Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 23168 Accepted: ...
- linux 下配置jdk
去java官方地址下载相应的源码包我下载的是1.8.0放在usr/local目录下 export JAVA_HOME=/usr/local/jdk1.8.0export PATH=$JAVA_HOME ...
- 【BZOJ4769】超级贞鱼 归并排序求逆序对
[BZOJ4769]超级贞鱼 Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的左脚和右脚上各有一个数.有一天,K只贞鱼兴致来潮,排成一列,从左到右第i ...
- ArcGIS Scalebar 比例尺 充满div
说明:本篇博文地图充满div,上一篇博文是充满整个body 运行效果: 2.HTML代码 <!DOCTYPE html> <html> <head> <met ...
- GridView 显示行号 设置行号列的宽度
/// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...
- iptables的例子1
练习1:实现主机防火墙 设置主机防火墙策略为DROP: iptables -t filter -P INPUT DROP iptables -t filter -P OUTPUT DROP i ...
- 【译】常见 Java 异常解释(恶搞版)
常见 Java 异常解释:(译者注:非技术角度分析.阅读有风险,理解需谨慎o(╯□╰)o) java.lang ArithmeticException 你正在试图使用电脑解决一个自己解决不了的数学问题 ...
- Android系统移植与调试之------->如何修改Android自带的apk出现一圈圈类似鸡蛋的花纹
最近被一个问题烦恼到了,就是android4.1系统自带的Email.文件管理器.信息等apk都出现同一个问题,就是现实在平板上的时候会出现一圈圈类似鸡蛋的花纹. 我想了两种方法来解决,第一种方法没有 ...
- liferay 指定默认首页
1.登录liferay后,点击控制面板-->设置--> portal设置 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3hpbmdf ...