迷宫城堡 HDU - 1269 判断有向图是否是强连通图

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

Input输入包含多组数据,输入的第一行有两个数:N和M,接下来的M行每行有两个数a和b,表示了一条通道可以从A房间来到B房间。文件最后以两个0结束。
Output对于输入的每组数据,如果任意两个房间都是相互连接的,输出"Yes",否则输出"No"。
Sample Input

3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0

Sample Output

Yes
No

 

题解:

题目意思已经很明确了,就是让你去判断这个有向图是不是一个强连通图

只是要保证两方面:

1、只能有一个连通块

2、这一个连通块中只有且仅有一个点x的low[x]==dfn[x]。因为在tarjan过程中如果要想变成一个强连通图,那么一定除了x的剩下所有点的low肯定要指向其他点

 

代码:

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<map>
  6 #include<math.h>
  7 #include<set>
  8 #include<queue>
  9 using namespace std;
 10 typedef long long ll;
 11 const int maxn=10005;
 12 const int mod=26;
 13 const int INF=0x3f3f3f3f;
 14 const int block=300;
 15 struct edge
 16 {
 17     int v,next;
 18 } e[100005];
 19 int dfn[maxn],low[maxn],stacks[maxn];
 20 int head[maxn],visit[maxn],cnt,tot,index;
 21 void add_edge(int x,int y)
 22 {
 23     e[cnt].v=y;
 24     e[cnt].next=head[x];
 25     head[x]=cnt++;
 26 }
 27 int tarjan(int x)
 28 {
 29     dfn[x]=low[x]=++tot;
 30     stacks[++index]=x;
 31     visit[x]=1;
 32     for(int i=head[x]; i!=-1; i=e[i].next)
 33     {
 34         if(!dfn[e[i].v])
 35         {
 36             tarjan(e[i].v);
 37             low[x]=min(low[x],low[e[i].v]);
 38         }
 39         else if(visit[e[i].v])
 40         {
 41             low[x]=min(low[x],dfn[e[i].v]);
 42         }
 43     }
 44     if(dfn[x]==low[x])
 45     {
 46         do{
 47             visit[stacks[index]]=0;
 48             index--;
 49         }while(x!=stacks[index+1]);
 50     }
 51 }
 52 int main()
 53 {
 54     int n,m;
 55     while(~scanf("%d%d",&n,&m))
 56     {
 57         if(!n && !m) break;
 58         cnt=0;
 59         for(int i=1;i<=n;++i)
 60         {
 61             head[i]=-1;
 62             visit[i]=0;
 63             dfn[i]=0;
 64             low[i]=0;
 65         }
 66         while(m--)
 67         {
 68             int x,y;
 69             scanf("%d%d",&x,&y);
 70             add_edge(x,y);
 71         }
 72         int flag=0;
 73         for(int i=1; i<=n; ++i)
 74         {
 75             if(!dfn[i])
 76             {
 77                 tarjan(i);
 78                 if(flag)
 79                 {
 80                     flag=2;
 81                     break;
 82                 }
 83                 else flag=1;
 84             }
 85             int ans=0;
 86             for(int i=1;i<=n;++i)
 87             {
 88                 if(dfn[i] && dfn[i]==low[i])
 89                 {
 90                     ans++;
 91                 }
 92                 if(ans>1)
 93                 {
 94                     flag=2;
 95                     break;
 96                 }
 97             }
 98         }
 99         if(flag==1)
100         {
101             printf("Yes\n");
102         }
103         else printf("No\n");
104     }
105     return 0;
106 }
View Code

 

posted @ 2019-10-13 15:00  kongbursi  阅读(400)  评论(0编辑  收藏  举报