#include<bits/stdc++.h>
using namespace std;
int e[10][10];
int c[10];
stack<int> s;
int n,m;
bool dfs(int u)
{
c[u]=-1;
for(int v=1; v<=n; v++)
{
if(e[u][v]==1)
{
if(c[v]==-1)
return false;
if(c[v]==0 && !dfs(v))
return false;
}
}
c[u]=1;s.push(u);
return true;
}
bool toposort()
{
memset(c,0,sizeof(c));
for(int i=1; i<=n; i++)
{
if(c[i]==0 && !dfs(i))
return false;
}
return true;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i=1; i<=m; i++)
{
int a,b;
scanf("%d%d", &a, &b);
e[a][b]=1;
}
if(toposort())
{
while(!s.empty())
{
printf("%d ", s.top());
s.pop();
}
}
}
之前是紫书上看的,这个是算法进阶指南上的,感觉这个思路更加清晰容易,这个是用邻接表存有向图,如果a在b的前面那么a->b同时b的入度加一。拓扑排序就是先找入度为0的点,然后在广度优先遍历与这个点相邻的点,将它减去与x相邻的这个入度1之后看看是否为零,为零的话可取,最后判断数组a中是否有n个点,如果小于n的话是这个有向图中出现了环。
#include<bits/stdc++.h>
using namespace std;
int head[1005],ver[1005],nxt[1005],rudu[1005];
int tot=0;
int a[1005];
int cnt=0;
int n,m;
void add(int x,int y)
{
ver[++tot]=y;
rudu[y]++;
nxt[tot]=head[x];
head[x]=tot;
}
void topsort()
{
queue<int> q;
for(int i=1; i<=n; i++)
{
if(rudu[i]==0)
q.push(i);
}
while(q.size())
{
int x=q.front();
q.pop();
a[++cnt]=x;
for(int i=head[x]; i; i=nxt[i])
{
int y=ver[i];
if(--rudu[y]==0)
q.push(y);
}
}
}
int main()
{
cin>>n>>m;
for(int i=1; i<=m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
topsort();
if(cnt==n)
{
for(int i=1; i<=n; i++)
printf("%d ",a[i]);
}
else
printf("No");
}