Day3 Tarjan
代码如下(示例):
#include <bits/stdc++.h>
using namespace std;
const int MaxN=1e4+5;//最大点数
const int MaxM=5e4+5;//最大边数
int to[MaxM],nex[MaxM],fir[MaxN];
int col,num,dfn[MaxN],low[MaxN],de[MaxN],si[MaxN];
int tot=0,co[MaxN],n,m;
int top,st[MaxN];
inline void Ins(int x,int y){//链式前向星
to[++tot]=y;
nex[tot]=fir[x];
fir[x]=tot;
}
void Tarjan(int u){//缩点
dfn[u]=low[u]=++num;
st[++top]=u;//模拟栈
for(int i=fir[u];i;i=nex[i]){
int v=to[i];
if(!dfn[v]){
Tarjan(v);//先将子树的状态完成
low[u]=min(low[u],low[v]);
}
else if(!co[v])//还在栈中
low[u]=min(low[u],low[v]);
}
if(low[u]==dfn[u]){
co[u]=++col;
++si[col];
while(st[top]!=u){
++si[col];
co[st[top]]=col;
--top;
}
--top;
}
}
int main(){
cin>>n>>m;
for(int i=1,x,y;i<=m;i++){
cin>>x>>y;
Ins(y,x);//反向建边
}
for(int i=1;i<=n;i++){
if(!dfn[i])
Tarjan(i);//缩点
}
for(int i=1;i<=n;i++)
for(int j=fir[i];j;j=nex[j])
if(co[i]!=co[to[j]])
de[co[to[j]]]++;//入度增加
int ans =0,u=0;
for(int i=1;i<=col;i++)
if(!de[i])
ans=si[i],u++;//统计
if(u==1)
cout<<ans<<endl;
else
cout<<0<<endl;
return 0;
}