您的位置:首页 > 其它

hdu 迷宫城堡 极大强连通分量的tarjan算法模板题

2012-08-15 23:10 381 查看
/*极大强连通分量的tarjan算法模板题。*/
#include<iostream>
#include <stdio.h>
#include <cstring>
using namespace std;

struct EDGE
{
int to,next;
} e[100005];   //边结点数组

int head[10010],stack[10010],DFN[10010],Low[10010],Belong[100010];
//  head[]头结点数组,stack[]为栈,DFN[]为深搜次序数组,Belong[]为每个结点所对应的强连通分量标号数组
//      Low[u]为u结点或者u的子树结点所能追溯到的最早栈中结点的次序号
int instack[10010],cnt,scnt,top,n,tot;
// instack[]为是否在栈中的标记数组
void add(int u,int v)
{
e[tot].to=v;
e[tot].next=head[u];
head[u]=tot++;
}
void tarjan(int u)
{
int j,t;
DFN[u]=Low[u]=++cnt;//边的搜索次序,要和边的标号对应,从1-->n
stack[top++]=u;//入栈
instack[u]=1;
for(int i=head[u]; i!=-1; i=e[i].next)
{
j=e[i].to;
if(!DFN[j])
{
tarjan(j);
Low[u]=min(Low[j],Low[u]);//注意这个地方,要用他的儿子节点去更新本身.
}
else if(instack[j]) Low[u]=min(Low[j],Low[u]);
}
if(Low[u]==DFN[u])
{
scnt++;
do
{
t=stack[--top];
Belong[t]=scnt;
instack[t]=0;
}
while(u!=t);
}
}
void solve()
{
top=scnt=cnt=0;
memset(DFN,0,sizeof(DFN));
for(int i=1; i<=n; i++)
{
if(!DFN[i]) tarjan(i);
}
}
int main()
{
int m,x,y;
while(scanf("%d%d",&n,&m)==2&&(n+m))
{
tot=1;
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d%d",&x,&y);
add(x,y);
}
solve();
if(scnt==1) printf("Yes\n");//极大强连通分量只有一个,说明该图是一个强连通图
else printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: