图的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.区别 ...
随机推荐
- 解决ListView滑动上下出现阴影
网上大部分说在listview的属性中通过设置android:fadingEdge="none"来解决问题,需要说明的是是在2.3版本之前有效! 方法一. public class ...
- 纯JS实现动态时间
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- iOS启动页加载广告
1.定义全局成员变量 @interface AppDelegate () @property (strong, nonatomic) UIImageView *adImageView; @proper ...
- 内存使用分析工具Valgrind简单用法
转载自 http://www.cnblogs.com/sunyubo/archive/2010/05/05/2282170.html 暂时还未使用过,记录下,记录下,记录下 Valgrind的主要作者 ...
- Python中为什么要使用线程池?如何使用线程池?
系统处理任务时,需要为每个请求创建和销毁对象.当有大量并发任务需要处理时,再使用传统的多线程就会造成大量的资源创建销毁导致服务器效率的下降.这时候,线程池就派上用场了.线程池技术为线程创建.销毁的开销 ...
- java面向对象入门之方法参数的传递
/* Name : Power by :Stuart Date:2015.4.25 */ class PassOn{ //创建show方法,把i传入,输出i+1的结果 public void show ...
- 销售订单、外向交货单、交货 bapi
转自[http://www.cnblogs.com/elegantok/archive/2009/10/18/1585398.html]***********SALES ORDER INPUT CRE ...
- virt-v2v 使用指南
virt-v2v 使用指南 1.定义. virt-v2v将外部的虚拟化平台上的虚拟机转化到可以运行的KVM平台上.它可以读取在VMware.Xen运行Hyper-V和其他虚拟机管理程序上的Window ...
- Windows磁盘MBR结构详解
在之前的文章 Windows存储管理之磁盘结构详解 中介绍了Windows的磁盘结构和MBR.本文将对Windows Basic Disk中的MBR的结构进行介绍,帮助读者更好的了解Windows系统 ...
- python基础1 ---python简介
python基础 一.python前言 1.什么是编程语言 编程语言是程序员与计算机之间沟通的介质. 2.编程语言的分类 机器语言:机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集 ...