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

来源:互联网 发布:中文域名的作用 编辑:程序博客网 时间:2024/05/18 03:06

/*极大强连通分量的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;}