Study notes: Topological sort

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;
}

Guess you like

Origin blog.csdn.net/m0_50815157/article/details/113725493