标签: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