hdu1269 迷宫城堡 (强连通分量Tarjan算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269


题解:对于任意的i和j,至少存在一条路径可以从房间i到房间j,也存在一条路径可以从房间j到房间i。求强连通分量==1?


#include <stdio.h>
#include <string.h>
#define MAXN 10001

struct node
{
	int from,to,next;
}edge[10*MAXN];

int head[MAXN],instack[MAXN],low[MAXN],dfn[MAXN];
int stack[MAXN],tot,Dindex,top,Bcnt;

void Init()
{//初始化
	tot=0,top=0,Dindex=0,Bcnt=0;
	memset(head,-1,sizeof(head));
	memset(instack,0,sizeof(instack));
	memset(dfn,0,sizeof(dfn));
	memset(low,0,sizeof(low));
}

void addEdge(int from,int to)
{
	edge[tot].from=from;
	edge[tot].to=to;
	edge[tot].next=head[from];
	head[from]=tot++;
}

void Tarjan(int x)
{
	int i,u,temp;
	dfn[x]=low[x]=++Dindex;//时间戳
	stack[top++]=x;
	instack[x]=1;
	for(i=head[x];i!=-1;i=edge[i].next)
	{
		u=edge[i].to;
		if(!dfn[u])
		{
			Tarjan(u);
			low[x]=low[x]>low[u]?low[u]:low[x];
		}
		else if(instack[u]&&low[x]>dfn[u])
			low[x]=dfn[u];
	}
	if(low[x]==dfn[x])
	{
		Bcnt++;
		do 
		{
			temp=stack[--top];
			instack[temp]=0;
		} while (x!=temp);
	}
}

int Scan()        
{        
	char ch;        
	int ret=0;        
	while((ch=getchar())<'0'||ch>'9');        
	while(ch>='0'&&ch<='9')        
	{        
		ret=ret*10+(ch-'0');        
		ch=getchar();        
	}        
	return ret;        
}   

int main()
{
	int n,m,i,x,y;
	while(scanf("%d %d",&n,&m)&&(n+m)!=0)
	{
		Init();
		while(m--)
		{
			//scanf("%d %d",&x,&y);
			x=Scan();
			y=Scan();
			addEdge(x,y);
		}
		for(i=1;i<=n;++i)
		{
			if(!dfn[i])
				Tarjan(i);
		}
		if(Bcnt==1)
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值