我的第一道tarjin
要注意两点,有向图一定要判断点是否在栈中
弹栈的时候不能判断low[x]==low[stack[top]]
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=5005;
const int MAXM=5000005;
inline int read(){
int x=0,f=1,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int nxt[MAXM],to[MAXM],h[MAXN],cnt;
inline void add(int x,int y){
nxt[cnt]=h[x];to[cnt]=y;h[x]=cnt++;
}
int dfn[MAXN],low[MAXN],vis[MAXN],tim;
int stack[MAXN],top;
int shu[MAXN],num;
inline void dfs(int x){
dfn[x]=low[x]=++tim;
vis[x]=1;
stack[++top]=x;
for(int i=h[x];i!=-1;i=nxt[i]){
if(!dfn[to[i]]) dfs(to[i]),low[x]=min(low[x],low[to[i]]);
else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
}
if(dfn[x]==low[x]){
num++;
while(stack[top]!=x&&top) shu[stack[top]]=num,vis[stack[top]]=0,top--;
shu[stack[top]]=num,vis[stack[top]]=0,top--;
}
}
int du[MAXN];
int main(){
int n=read();
while(n!=0){
memset(h,-1,sizeof(h));
memset(du,0,sizeof(du));
memset(dfn,0,sizeof(dfn));
memset(vis,0,sizeof(vis));
top=0,tim=0,cnt=0,num=0;
int m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
add(x,y);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
dfs(i);
for(int i=1;i<=n;i++)
for(int j=h[i];j!=-1;j=nxt[j])
if(shu[i]!=shu[to[j]])
du[shu[i]]++;
for(int i=1;i<=n;i++)
if(!du[shu[i]])
printf("%d ",i);
puts("");
n=read();
}
return 0;
}