标签:acm algorithm hdu tarjan 强连通分量
3 3 1 2 2 3 3 1 3 3 1 2 2 3 3 2 0 0
Yes No
题意:判断一个图是否是强连通图。
分析:强连通分量。如果该图中只有一个强连通分量,那么就是强连通图。第一次写tarjan,照着别人代码敲的。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1269
#include<map> #include<cmath> #include<queue> #include<stack> #include<ctime> #include<cctype> #include<string> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; const int maxn = 10000 + 5; const int maxv = 100000 + 5; int N,M,a,b; vector<int>G[maxn]; //邻接表存图 stack<int>sta; //存储已遍历的节点 int dfn[maxn]; //深度优先访问次序 int low[maxn]; //能追溯到的最早次序 bool InStack[maxn]; //是否在栈中 int index; //索引号 int cnt; //强连通分量个数 void init(){ for(int i=1;i<=N;i++) G[i].clear(); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(InStack,false,sizeof(InStack)); index=0; cnt=0; while(!sta.empty()) sta.pop(); } void tarjan(int u){ low[u]=dfn[u]=++index; sta.push(u); InStack[u]=true; for(int i=0;i<G[u].size();i++){ int v=G[u][i]; if(dfn[v]==0){ tarjan(v); low[u]=min(low[u],low[v]); } if(InStack[v]){ low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]){ cnt++; while(!sta.empty()){ int j=sta.top(); sta.pop(); InStack[j]=false; if(j==u) break; } } } void input(){ for(int i=0;i<M;i++){ scanf("%d%d",&a,&b); G[a].push_back(b); } } void solve(){ for(int i=1;i<=N;i++){ if(!dfn[i]) tarjan(i); if(cnt>1) break; } if(cnt>1) printf("No\n"); else printf("Yes\n"); } int main(){ while(scanf("%d%d",&N,&M)!=EOF&&N+M){ init(); input(); solve(); }return 0; }
标签:acm algorithm hdu tarjan 强连通分量
原文地址:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/45691933