强连通分量分解 tarjan算法 (hdu 1269)

题意:

给出一个有n个点m条边的有向图,判断该图是否只有一个强连通分量。

限制:

0 <= N <= 10000

0 <= M <= 100000

思路:

tarjan算法分解强连通分量。

/*强连通分量分解 tarjan算法 (hdu 1269)
  题意:
  给出一个有n个点m条边的有向图,判断该图是否只有一个强连通分量。
  限制:
  0 <= N <= 10000
  0 <= M <= 100000
 */
#include<iostream>
#include<cstdio>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int MAX_V = 1e5+5;
#define PB push_back

vector<int> G[MAX_V];
stack<int> tarjan_stack;
int DFN[MAX_V], LOW[MAX_V];
int tarjan_set[MAX_V];
bool in_stack[MAX_V];
int scc_cnt, tarjan_cnt;
void tarjan(int u){
	DFN[u] = LOW[u] = ++tarjan_cnt;
	tarjan_stack.push(u);
	in_stack[u] = true;

	for(int i = 0; i < G[u].size(); ++i){
		int ch = G[u][i];
		if(!DFN[ch]){
			tarjan(ch);
			LOW[u] = min(LOW[u], LOW[ch]);
		} else if(in_stack[ch]){
			LOW[u] = min(LOW[u], DFN[ch]);
		}
	}

	if(DFN[u] == LOW[u]){
		int tmp;
		++scc_cnt;
		do{
			tmp = tarjan_stack.top(); tarjan_stack.pop();
			in_stack[tmp] = false;
			tarjan_set[tmp] = scc_cnt;
		}
		while(tmp != u);
	}
}
void add_edge(int u,int v){
	G[u].PB(v);
}
void init_tarjan(int n){
	scc_cnt = tarjan_cnt = 0;
	memset(DFN, 0, sizeof(DFN));
	memset(LOW, 0, sizeof(LOW));
	memset(in_stack, 0, sizeof(in_stack));
	memset(tarjan_set, 0, sizeof(tarjan_set));
	for(int i = 0; i <= n; ++i)
		G[i].clear();
}
//点的序号从0开始
void gao(int n){
	for(int i = 0; i < n; ++i){
		if(!DFN[i]) tarjan(i);
	}
	for(int i = 1; i < n; ++i){
		if(tarjan_set[i] != tarjan_set[i-1]){
			puts("No");
			return ;
		}
	}
	puts("Yes");
}
int main(){
	int n, m;
	while(scanf("%d%d", &n, &m) && (n || m)){
		init_tarjan(n);
		for(int i = 0; i < m; ++i){
			int u, v;
			scanf("%d%d", &u, &v);
			add_edge(u-1, v-1);
		}
		gao(n);
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 20:51:37

强连通分量分解 tarjan算法 (hdu 1269)的相关文章

hdu1269 迷宫城堡,有向图的强连通分量 , Tarjan算法

hdu1269 迷宫城堡 验证给出的有向图是不是强连通图... Tarjan算法板子题 Tarjan算法的基础是DFS,对于每个节点.每条边都搜索一次,时间复杂度为O(V+E). 算法步骤: 1.搜索到某一个点时,将该点的Low值标上时间戳,然后将自己作为所在强连通分量的根节点(就是赋值Dfn=Low=time) 2.将该点压入栈. 3.当点p有与点p'相连时,如果此时p'不在栈中,p的low值为两点的low值中较小的一个. 4.当点p有与点p'相连时,如果此时p'在栈中,p的low值为p的lo

【转载】有向图强连通分量的Tarjan算法

from byvoid [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为

算法笔记_144:有向图强连通分量的Tarjan算法(Java)

目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. 定义D

强连通分量的Tarjan算法

资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tarjan算法详解理解集合 ppt图解分析下载 强连通分量 强连通分量(strongly connected component)是图论中的概念.图论中,强连通图指每一个顶点皆可以经由该图上的边抵达其他的每一个点的有向图.意即对于此图上每一个点对(Va,Vb),皆存在路径Va→Vb以及Vb→Va.强连通

有向图强连通分量的Tarjan算法(转)

原文地址:有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强

有向图强连通分量的Tarjan算法——转自BYVoid

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的

有向图强连通分量的Tarjan算法

有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,

【转】有向图强连通分量的Tarjan算法

原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量

poj1236 Network of Schools ,求强连通分量(Tarjan算法),缩点

题目链接: 点击打开链接 题意: 给定一个有向图,求: 1) 至少要选几个顶点,才能做到从这些顶点出发,可以到达全部顶点 2) 至少要加多少条边,才能使得从任何一个顶点出发,都能到达全部顶点 顶点数<= 100 求完强连通分量后,缩点,计算每个点的入度,出度. 第一问的答案就是入度为零的点的个数, 第二问就是max(n,m) // 入度为零的个数为n, 出度为零的个数为m. //kuangbin巨巨分析很棒! #include<cstdio> #include<cstring>