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;}