【模板】 有向图的拓扑排序

传送门

题意

给定\(n\)\(m\)边的有向图,可能存在重边,输出任意一个这个图的拓扑序列,如果不存在输出\(-1\)

数据范围

\(1 \leq n, m \leq 10^{5}\)

题解

有向无环图是拓扑排序的关键
\(bfs\),选择入度为\(0\)的点,不断的将入度为\(0\)的点加入答案序列,并将它所有出边的终点的度\(-1\)
如果存在拓扑序列,那么最后的答案数组长度就是节点个数,如果不存在,即过程进行到某一步后不存在入度为\(0\)的节点,结束,节点的个数就不到\(n\)

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=1;i--)
const int N=1e5+10;
struct node
{
   int to,ne;
}e[N];
int h[N],idx;
int deg[N],ans[N],cnt;
int n,m;
void add(int a,int b)
{
   e[++idx].to=b;
   e[idx].ne=h[a];
   h[a]=idx;
   deg[b]++;
}
bool topsort()
{
   queue<int>q;
   rep(i,1,n+1) if(deg[i]==0) q.push(i);
   while(q.size())
   {
      int t=q.front(); q.pop();
      ans[++cnt]=t;
      for(int i=h[t];i;i=e[i].ne)
      {
         int to=e[i].to;
         if(--deg[to] == 0) q.push(to);
      }
   }
   return cnt==n?1:0;
}
int main()
{
   cin>>n>>m;
   while(m--)
   {
      int a,b;
      cin>>a>>b;
      add(a,b);
   }
   if(topsort()) rep(i,1,n+1) cout<<ans[i]<<' ';
   else cout<<"-1"<<endl;
}
posted @ 2020-10-11 01:56  Hyx'  阅读(190)  评论(0)    收藏  举报