Topological sorting of a Directed Acyclic Graph (DAG for short) G is to arrange all vertices in G into a linear sequence, so that any pair of vertices u and v in the graph, if the edge <u,v>∈ E(G), then u appears before v in the linear sequence. Generally, such a linear sequence is called a sequence that satisfies the topological order (Topological Order), or topological sequence for short. Simply put, a partial order on a certain set is obtained by a total order on the set. This operation is called topological sorting.
Topological sequence of a directed graph:
Given a directed graph with n points and m edges, the points are numbered from 1 to n, and there may be multiple edges and self-loops in the graph.
Please output any topological sequence of the directed graph. If the topological sequence does not exist, output -1.
If a sequence A composed of all points in the graph satisfies: For each edge (x, y) in the graph, x appears before y in A, then A is a topological sequence of the graph.
Input format The
first line contains two integers n and m
followed by m lines. Each line contains two integers x and y, indicating that there is a directed edge (x, y) from point x to point y.
The output format
has one line. If there is a topology sequence, output any legal topology sequence. Otherwise, output -1.
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstring>
#include<iostream>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#define ll long long
#define ull unsigned long long
#define up_b upper_bound
#define low_b lower_bound
#define m_p make_pair
#define mem(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define inf 0x3f3f3f3f
#define endl "\n"
#include<algorithm>
using namespace std;
inline ll read()
{
ll x=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar(); }
while('0'<=ch&&ch<='9') x=x*10+ch-'0', ch=getchar();
return f*x;
}
const int N = 1e5+5;
int n,m,in[N];
struct node{
int v,next;}edge[N];
int head[N],idx;
void add(int u,int v)
{
edge[idx]=(node){
v,head[u]};
head[u]=idx++;
}
vector<int> path;
bool topo()
{
queue<int> q; //如果要求输出字典序最小的拓扑序列,可以用优先队列
for(int i=1;i<=n;i++)
if(in[i]==0) q.push(i);
while(!q.empty())
{
int u=q.front(); q.pop();
path.push_back(u);
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].v;
in[v]--;
if(in[v]==0) q.push(v);
}
}
return path.size()==n; //如果最终入队的点数不足n点,说明图中出现了环,不存在拓扑排序
}
int main()
{
memset(head,-1,sizeof(head));
cin>>n>>m;
while(m--)
{
int u=read(),v=read();
add(u,v);
in[v]++; //入度
}
if(topo())
{
for(int i=0;i<path.size();i++) cout<<path[i]<<" ";
}
else cout<<-1<<endl;
return 0;
}