94 lines
1.5 KiB
C++
94 lines
1.5 KiB
C++
// ´Þ¶«Ðñ 46ms
|
|
#include<cstdio>
|
|
using namespace std;
|
|
struct edge
|
|
{
|
|
int to,nxt;
|
|
};
|
|
int fmin(int a,int b)
|
|
{
|
|
return a<b? a:b;
|
|
}
|
|
edge a[10000010];
|
|
int n,e,cnt,head[50010],belong[50010],out[50010];
|
|
int stack[50010],s_head,dnf[50010],low[50010],visit,newp;
|
|
int vis[50010];
|
|
void add(int x,int y)
|
|
{
|
|
a[++cnt].to=y;
|
|
a[cnt].nxt=head[x];
|
|
head[x]=cnt;
|
|
}
|
|
void tarjan(int now)
|
|
{
|
|
int tx,ty;
|
|
dnf[now]=low[now]=++visit;
|
|
stack[++s_head]=now;
|
|
vis[now]=1;
|
|
for(tx=head[now]; tx; tx=a[tx].nxt)
|
|
{
|
|
ty=a[tx].to;
|
|
if(vis[ty]==0)
|
|
{
|
|
tarjan(ty);
|
|
low[now]=fmin(low[now],low[ty]);
|
|
}
|
|
if(vis[now]==1)
|
|
{
|
|
low[now]=fmin(low[now],low[ty]);
|
|
}
|
|
}
|
|
if(low[now]==dnf[now])
|
|
{
|
|
newp++;
|
|
while(stack[s_head]!=now)
|
|
{
|
|
vis[stack[s_head]]=2;
|
|
belong[stack[s_head--]]=newp;
|
|
}
|
|
vis[stack[s_head]]=2;
|
|
belong[stack[s_head--]]=newp;
|
|
}
|
|
return;
|
|
}
|
|
void work(int now)
|
|
{
|
|
int tx,ty;
|
|
for(tx=head[now]; tx; tx=a[tx].nxt)
|
|
{
|
|
ty=a[tx].to;
|
|
if(belong[now]!=belong[ty]) out[belong[now]]++;
|
|
}
|
|
return;
|
|
}
|
|
int main()
|
|
{
|
|
// freopen("1.txt","r",stdin);
|
|
// freopen("2.txt","w",stdout);
|
|
int tx,ty;
|
|
while(1)
|
|
{
|
|
scanf("%d",&n);
|
|
if(n==0) break;
|
|
scanf("%d",&e);
|
|
for(int i=1; i<=e; i++)
|
|
{
|
|
scanf("%d%d",&tx,&ty);
|
|
add(tx,ty);
|
|
}
|
|
for(int i=1; i<=n; i++)
|
|
{
|
|
if(vis[i]==0) tarjan(i);
|
|
}
|
|
for(int i=1; i<=n; i++) work(i);
|
|
for(int i=1; i<=n; i++)
|
|
{
|
|
if(out[belong[i]]==0) printf("%d ",i);
|
|
}
|
|
printf("\n");
|
|
for(int i=1; i<=n; i++) head[i]=belong[i]=out[i]=vis[i]=0;
|
|
cnt=newp=visit=0;
|
|
}
|
|
return 0;
|
|
}
|