迷宫城堡 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 }