hdu 1269 夜

http://acm.hdu.edu.cn/showproblem.php?pid=1269

题目大意:

给你一个迷宫 给你结点个数和一定数目的单向边

问你迷宫是否强连通

做这道题这是为了练习一下Tarjan算法

关于这个算法网上很多而已版本 大多都一样 我就不多说了

详解见代码注释

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>

using namespace std;
const int N=10005;
struct node
{
    struct tt *next;
}mem[N];
struct tt
{
    int b;
    struct tt *next;
};
int low[N];//逆向边可达最前父结点
int dfn[N];//深度
bool in[N];//是否在栈里面
bool visited[N];//是否访问过
stack<int>str;
void build(int a,int b)//建邻接表
{
    struct tt *t=new tt;
    t->b=b;
    t->next=mem[a].next;
    mem[a].next=t;
}
int deep,num;//深度 和 访问结点的个数
bool Tarjan(int x)
{
   ++deep;
   low[x]=dfn[x]=deep;//初始化
   str.push(x);
   in[x]=true;
   visited[x]=true;++num;
   struct tt *t=mem[x].next;
   while(t!=NULL)
   {
       if(visited[t->b]==false)//如果没访问过 则深搜
       {
           if(Tarjan(t->b)==false)//如果已经不合题意 则可停止
           return false;
           low[x]=min(low[x],low[t->b]);
       }
       else if(in[t->b]==true)//如果在栈里面 
       {
           low[x]=min(low[x],dfn[t->b]);
       }
       t=t->next;
   }
   /*
   while(t!=NULL)//本来想看这样对不对 因为网上的代码都是上面的 我感觉下面的也对 
   {//提交也对了 也可能是只适合本题 亦可能这个本身也对 以后还须继续证明
       if(visited[t->b]==false)
       {
           if(Tarjan(t->b)==false)
           return false;
       }
       low[x]=min(low[x],low[t->b]);
       t=t->next;
   }
   */
   if(dfn[x]==low[x])
   {
       if(x!=1)//从 1 开始搜的 唯一的连同分支根结点是 1 否则就错
       return false;
       return true;
   }
   return true;

}
void clear(int n)//每次要对邻接表表头进行处理
{
    for(int i=1;i<=n;++i)
    mem[i].next=NULL;
}
int main()
{
    int n,m;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        deep=0;
        num=0;
        if(n==0&&m==0)
        break;
        while(m--)
        {
            int a,b;
            scanf("%d %d",&a,&b);
            build(a,b);
        }
        memset(in,false,sizeof(in));
        memset(visited,false,sizeof(visited));
        if(Tarjan(1)&&num==n)//注意要满足 每个点都被访问过
        printf("Yes\n");
        else
        printf("No\n");
        clear(n);

    }
    return 0;
}

原文地址:https://www.cnblogs.com/liulangye/p/2522383.html