HDU ACM 1269迷宫城堡->有向强连通分量(tarjan算法实践)

分析:本题判断一个图是否是有向强连通分量,这里使用tarjan算法求解。

#include<iostream>
#include<vector>
#include<stack>
using namespace std;

vector<int> map[10002];
stack<int> tarjan_stack;
int low[10002];
int dfn[10002];
bool vis[10002];
int cnt,pos;

void Init(int n)
{
	int i;

	cnt=pos=0;
	memset(low,0,sizeof(low));
	memset(dfn,0,sizeof(dfn));
	memset(vis,0,sizeof(vis));

	for(i=1;i<=n;i++)
		map[i].clear();

	while(!tarjan_stack.empty()) tarjan_stack.pop();
}

void Input(int m)
{
	int i,a,b;

	for(i=1;i<=m;i++)
	{
		cin>>a>>b;
		map[a].push_back(b);
	}
}

void tarjan(int u)
{
	int i,t;

	dfn[u]=low[u]=++pos;
	vis[u]=true;
	tarjan_stack.push(u);

	for(i=0;i<map[u].size();i++)
	{
		t=map[u][i];
		if(!dfn[t])
		{
			tarjan(t);
			if(low[t]<low[u])
				low[u]=low[t];
		}
		else if(vis[t] && low[u]>dfn[t])
			low[u]=dfn[t];
	}
	if(low[u]==dfn[u])
	{
		cnt++;

		while(!tarjan_stack.empty())
		{
	    	t=tarjan_stack.top();
	    	tarjan_stack.pop();
			vis[t]=false;
			if(t==u) break;
		}
	}
}

void Solve(int n,int m)
{
	int i;

	Init(n);
	Input(m);

	for(i=1;i<=n;i++)     //循环防止是森林的情况也能处理
		if(!dfn[i])
			tarjan(i);

	if(cnt==1)
		puts("Yes");
	else
		puts("No");
}

int main()
{
	int N,M;

	while(cin>>N>>M &&(N||M))
	{
		Solve(N,M);
	}
	return 0;
}
时间: 2024-11-05 10:24:24

HDU ACM 1269迷宫城堡->有向强连通分量(tarjan算法实践)的相关文章

HDU 1269 强连通分量tarjan算法

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6655    Accepted Submission(s): 2973 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房

图之强连通、强连通图、强连通分量 Tarjan算法

强连通分量 简介 在阅读下列内容之前,请务必了解图论基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Components,SCC)的定义是:极大的强连通子图. 这里想要介绍的是如何来求强连通分量. Tarjan 算法 Robert E. Tarjan (1948~) 美国人. Tarjan 发明了很多算法结构.光 Tarjan 算法就有很多,比如求各种联通分量的 Tarjan 算法,求 LCA(Lowest Comm

求图的强连通分量--tarjan算法

一:tarjan算法详解 ?思想: ? ?做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间最早的节点的开始时间.(也就是之后的深搜所能到达的最小开始时间)初始时dfn[i]=low[i] ? ?在DFS过程中会形成一搜索树.在搜索树上越先遍历到的节点,显然dfn的值就越小. ? ?DFS过程中,碰到哪个节点,就将哪个节点入栈.栈中节点只有在其所属的强连通分量已经全部求出时,才会出栈. ?

poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】

题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27496   Accepted: 11059 Description Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows

图论-强连通分量-Tarjan算法

有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在百科上和别的大神的博客中不太一样,暂且采用百科上的定义) Tarjan算法的功能就是求有向图中的强连通分量 思路: 定义DFNi存放访问到i结点的次序(时间戳),Lowi存放i结点及向i下方深搜到的结点中能追溯到的访问次序最小的结点的访问次序(即这些结点回溯上去能找到的最小的DFN值),找到未被访问

强连通分量--tarjan算法

今天学了一个强连通分量,用tarjan做.北京之前讲过,今天讲完和之前一样,没有什么进步.上课没听讲,只好回来搞,这里安利一个博客:链接 https://blog.csdn.net/qq_34374664/article/details/77488976 讲一下我自己的体会吧,其实就是维护一个栈,然后树上跑dfs,每个节点存两个值:dn和low,dn代表dfs的顺序(时间),low代表的是他可以连通的最小的节点. 模拟一下,然后就会发现,其实整个算法就是模拟了一下将每个点压入栈.然后遇到之前在栈

HDU 1269 迷宫城堡 (强联通分量,Tarjan算法)

Problem Description: 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A房间和B房间,只说明可以通过这个通道由A房间到达B房间,但并不说明通过它可以由B房间到达A房间.Gardon需要请你写个程序确认一下是否任意两个房间都是相互连通的,即:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i. Input: 输入包含多组数据

HDU 1269 迷宫城堡 【强联通分量(模版题)】

知识讲解: 在代码里我们是围绕 low 和 dfn 来进行DFS,所以我们务必明白 low 和 dfn 是干什么的? 有什么用,这样才能掌握他. 1.  dfn[]  遍历到这个点的时间 2.  low[]  遍历到这个所能连接到的最短时间,说明那个最短时间可以遍历带他,他也可以走到那个最短时间. 3.  我们每次出栈的点就是一个强联通分量(这里建议观看一下课件里面的Tarjan求强联通算法的模拟过程). #include<cstdio> #include<cstdlib> #in

求强连通分量Tarjan算法

int dfn[16]; // 时间戳 int dfn_num = 0; // 时间 int low[16]; // 节点u所能访问到的最小时间戳 int inSt[16]; // 节点u是否在栈中. int st[16]; int top = 0; // 我们维护的信息. int col[16]; // 给节点染色, 同一个连通块的节点应该是同一个颜色的. int col_num = 0; // 颜色值. int size[16]; // 每个颜色值所拥有的块数. /* 第一步: 访问当前节点