概要

在一个有向无环图中,对其所有顶点进行拓补排序,就是将所有顶点排成一个序列,并使得序列中所有的点满足对于边<u,v>,若u到v是可达的,则u在拓补序列中一定出现在v之前。

过程

①找到当前入度为0的点,加入拓补序列
②将找到的入度为0的点的出边和该点删除
③重复上面两个步骤

简要实现

图的存储方式不止一种
使用数组f[]储存每个点地入度;
将入度为0地点放入栈或者队列中;
每次删除要使对应被删除的边地入度减一;

最后

当所有的点都已经删除则拓补排序完成,同时,栈或队列为空,若不为空,则说明图中存在环,这也是判断环的一种方法。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 80112002;
int g[5010][5010];
queue<int>q;
int in_degree[5010];
int f[5010];
int main()
{
int n,m;
cin>>n>>m;
while(m--)
{
int u,v;
cin>>u>>v;
g[u][v] = 1;
in_degree[v]++;
}
for(int i = 1; i <= n; i++)
{
if(in_degree[i] == 0)
{
f[i] = 1;
q.push(i);
}
}
ll ans = 0;
while(!q.empty())
{
int k = q.front();
q.pop();
cout<<k<<" ";
for(int i = 1; i <= n; i++)
{
if(!g[k][i])continue;
in_degree[i]--;
if(!in_degree[i])
{
q.push(i);
}
}
}
}