[算法系列]图论02-拓扑排序

101 阅读1分钟

拓扑排序

本节主要介绍图的拓扑排序,内容较为简单,但是拓扑排序又不太好与其他节并起来,因此只能单独一节

拓扑排序是根据一种先决关系,对图中节点进行排序的算法

算法步骤:

1.我们用邻接表存图,并且构建一个队列,一个d数组用于存储节点的入度

2.我们将入度为0的节点加入队列,队列不空时,我们取出队头元素,删除该节点

从与它邻接的点再次找入度为0的点,加入队列,直到队列为空

为了不额外消耗空间存储结果,我们可以用数组模拟队列,顺便存储结果,见下面的代码

代码实现:

给出一个模板题:

image.png

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N=1e5+10;
int n,m;
int h[N],e[N],ne[N],idx;
int d[N],q[N];
void add(int a,int b){
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}
bool topsort(){
    int hh=0,tt=-1;
    for(int i=1;i<=n;i++){
        if(!d[i]){
            q[++tt]=i;
        }
    }
    while(hh<=tt){
        int t=q[hh++];
        for(int i=h[t];i!=-1;i=ne[i]){
            int j=e[i];
            if(--d[j]==0){
                q[++tt]=j;
            }
        }
    }
    return tt==n-1;
}
int main(){
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        add(a,b);
        ++d[b];
    }
    if(!topsort())puts("-1");
    else{
        for(int i=0;i<n;i++){
            cout<<q[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}