强连通分量——Tarjan 算法模板
参考代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5,M=2e5+5;
int head[N],to[M],nxt[M],tot;
int dfn[N],s[N],low[N],cnt,top;
int sc;// SCC 个数
int scc[N];// 结点 i 所在 SCC 的编号
int sz[N];// 强连通 i 的大小
bool in[N];
void add(int u,int v){
nxt[++tot]=head[u];
head[u]=tot;
to[tot]=v;
}
void tarjan(int u){
low[u]=dfn[u]=++cnt;
s[++top]=u;
in[u]=1;
for(int i=head[u];i;i=nxt[i]){
int v=to[i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(in[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
++sc;
while(s[top]!=u){
scc[s[top]]=sc;
sz[sc]++;
in[s[top]]=0;
top--;
}
scc[s[top]]=sc;
sz[sc]++;
in[s[top]]=0;
top--;
}
}
int main(){
int n,m;
while(scanf("%d %d",&n,&m)&&(n||m)){
memset(dfn,0,sizeof(dfn));
memset(in,0,sizeof(in));
memset(s,0,sizeof(s));
memset(low,0,sizeof(low));
memset(head,0,sizeof(head));
memset(to,0,sizeof(to));
memset(nxt,0,sizeof(nxt));
sc=0;
cnt=tot=top=0;
for(int i=1;i<=m;i++){
int u,v;
scanf("%d %d",&u,&v);
add(u,v);
}
for(int i=1;i<=n;i++){
if(!dfn[i]){
tarjan(i);
}
}
if(sc==1) puts("Yes");
else puts("No");
}
return 0;
}
// hdu 1269 迷宫城堡