拓扑排序

拓扑排序

拓扑序列:一个有向图中,对于任意的边,拓扑排序的目标是将所有节点排序,使得排在前面的节点不能依赖于排在后面的节点。

可以证明,一个有向无环图一定存在拓扑序列,但不一定唯一

算法:

所有入度为零的点入队,删除该点和所有出边

枚举所有入队的点的指向的点,让其入度减1,若是这些点入度变为零,则入队;若是不为零,不管,直到其他点不断递归到指向它的点,使得入度最终变为零,再入队。

不断重复以上过程,直到集合 𝑆 为空。检查图中是否存在任何边(j==n-1),如果有,那么这个图一定有环路,否则返回 𝐿,𝐿 中顶点的顺序就是构造拓扑序列的结果。如果没有说明图是有环图

首先仍然需要图的储存

其中q代表队列,d代表点的入度

#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
const int N=10010;
int e[N],ne[N],h[N],idx;
int q[N],d[N];
void init(){
    idx=0;
    memset(h,-1,sizeof(h);
    
}
void add(int a,int b){
    e[idx]=b;ne[idx]=h[a];h[a]=idx;idx++;
    d[b]++
}

然后是toposort


bool toposort(){

    int j=-1,k=0;
    for(int i=0;i<n;i++) if(d[i]=0)q[++j]=i;
    while(k<=j){
    for(int head=h[q[k]];head!=-1;head=ne[head]){
    int nt=e[head];
    d[nt]--;
    if(d[nt]==0)q[++j]=nt;
}
}
    return j==n-1;
}

main函数中,输出topo序列的逻辑

发现我们q[]刚好就是节点的排序,满足前面的节点不依赖于后面的节点

if(toposort()){
    for(int i=0;i<n;i++)cout<<q[i]<<" ";
}
posted @ 2025-09-28 10:55  hardestnut  阅读(50)  评论(0)    收藏  举报