#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 1005
int g[maxn][maxn],flag[maxn],ans[maxn];
int n,m,cnt;
bool dfs(int t)
{
flag[t]=-1;
for(int i=0;i<n;i++)
{
if(g[t][i])
{
if(flag[i]==-1)return false;
if(!flag[i])dfs(i);
}
}
flag[t]=1;
ans[--cnt]=t;
return true;
}
bool topo()
{
for(int i=0;i<n;i++)
{
if(!flag[i])
{
if(!dfs(i))return false;
}
}
return true;
}
int main()
{
while(~scanf("%d%d",&n,&m)&&n!=0)
{
memset(g,0,sizeof(g));
memset(flag,0,sizeof(flag));
cnt=n;
for(int i=0;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
g[--x][--y]=1;
}
if(topo())
{
for(int i=0;i<n-1;i++)
printf("%d ",ans[i]+1);
printf("%d\n",ans[n-1]+1);
}
else printf("No\n");
}
return 0;
}
大体步骤:1状态标记:共三种,-1表示访问中,0表示未访问,1表示已访问,由数组flag保存
2.dfs终止的判别条件:如果存在环,则不存在,退出;反之把当前结点加入拓扑排序的首部(线性序列的当前第一个位置,随着排序的进行,这个位置会不断前移)
3.通过ans数组记录拓扑排序