114 lines
1.4 KiB
C++
114 lines
1.4 KiB
C++
#include<cstdio>
|
|
#include<string.h>
|
|
#include<algorithm>
|
|
using namespace std;
|
|
const int N=5e3+5,NN=N*N;
|
|
int n,e;
|
|
int to[NN],ne[NN];
|
|
int h[N];
|
|
int dfn[N],low[N];
|
|
bool b[N];
|
|
int s[N];//stack
|
|
int cnt;
|
|
int tot,top;
|
|
int id;
|
|
int nid[N];
|
|
int now;
|
|
bool no[N];
|
|
int ans[N];
|
|
int len;
|
|
void add(int u,int v)
|
|
{
|
|
to[++cnt]=v;
|
|
ne[cnt]=h[u];
|
|
h[u]=cnt;
|
|
}
|
|
void initialise(int n)
|
|
{
|
|
cnt=0;
|
|
tot=0;
|
|
top=0;
|
|
id=0;
|
|
len=0;
|
|
memset(b,0,sizeof(bool)*(n+1));
|
|
memset(no,0,sizeof(bool)*(n+1));
|
|
memset(h,0,sizeof(int)*(n+1));
|
|
}
|
|
void tarjan(int u)
|
|
{
|
|
// printf("%d ",u);
|
|
int v;
|
|
dfn[u]=++tot;
|
|
low[u]=tot;
|
|
s[++top]=u;
|
|
b[u]=1;
|
|
for(int i=h[u]; i; i=ne[i])
|
|
{
|
|
v=to[i];
|
|
if(!dfn[v])
|
|
{
|
|
tarjan(v);
|
|
low[u]=low[u]<low[v]? low[u]:low[v];
|
|
}
|
|
else
|
|
{
|
|
low[u]=low[u]<dfn[v]? low[u]:dfn[v];
|
|
}
|
|
}
|
|
if(low[u]==dfn[u])
|
|
{
|
|
id++;
|
|
now=s[top];
|
|
while(dfn[now]!=low[now])
|
|
{
|
|
nid[now]=id;
|
|
now=s[--top];
|
|
b[now]=0;
|
|
}
|
|
b[u]=0;
|
|
nid[u]=id;
|
|
}
|
|
}
|
|
int main()
|
|
{
|
|
int u,v;
|
|
while(~scanf("%d",&n)&&n)
|
|
{
|
|
initialise(n);
|
|
scanf("%d",&e);
|
|
for(int i=1; i<=e; i++)
|
|
{
|
|
scanf("%d%d",&u,&v);
|
|
add(u,v);
|
|
}
|
|
//一开始放在前面,忽略了没有边的情况
|
|
for(int i=1;i<=n;i++)
|
|
{
|
|
add(0,i);
|
|
}
|
|
tarjan(0);
|
|
for(int i=1; i<=n; i++)
|
|
{
|
|
for(int j=h[i]; j; j=ne[j])
|
|
{
|
|
v=to[j];
|
|
if(nid[v]!=nid[i])
|
|
{
|
|
no[nid[i]]=1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int j=1; j<=n; j++)
|
|
{
|
|
if(!no[nid[j]])
|
|
{
|
|
printf("%d ",j);
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
return 0;
|
|
}
|