【模板】 有向图的拓扑排序
传送门
题意
给定\(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;
}

浙公网安备 33010602011771号