首先解释一下什么是拓扑排序,比如打一场比赛,A打赢了B,B打赢了C……让你给出一个排名,这个过程用到的就是拓扑排序。

相当于说给了你一些条件使得某一个元素在排序时一定在另一个的前面,最后在排个序。

这个问题我们可以这样取处理,如果给出条件A不在B前面,那么我们建立一个A->B的有向边,不难发现,入度为0的点肯定是在最前面的,因为没有点一定在其前面。这个时候我们先把这个点去掉,剩下的点中我们同样可以找到一个入度为0的点,一定排在现在的最前面,我们重复这个步骤就能得到最后的序列,这个就是拓扑排序,如果其中有遇到找不到入度为0的点,那么这个序列就不存在一个拓扑排序排列。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#define LL __int64
using namespace std;
const int maxn = 100000+5;
int degree[maxn],topSort[maxn];
priority_queue<int> q;//优先大的ID在前面
vector<int> G[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0; i<=n; i++)
{
G[i].clear();
degree[i] = 0;
}
while(m--)
{
int a,b;
scanf("%d%d",&a,&b);
G[a].push_back(b);
degree[b]++;
}
for(int i=1; i<=n; i++)
if(degree[i] == 0)
q.push(i);
LL sum = 0;
int Min = n,num = 0;
while(!q.empty())
{
int u = q.top();
q.pop();
topSort[num++] = u;
for(int i=0; i<G[u].size(); i++)
{
int v = G[u][i];
degree[v]--;
if(degree[v] == 0)
q.push(v);
}
}
for(int i=0; i<n; i++)
{
if(i!=0) printf(" ");
printf("%d",topSort[i]);
}
printf("\n");
}
}