其他分享
首页 > 其他分享> > 拓扑排序(持续更新中···)

拓扑排序(持续更新中···)

作者:互联网

拓扑排序

对一个有向无环图 G G G 进行拓扑排序,是将 G G G 中所有顶点排成一个线性序列,使得图中任意一对顶点 u u u 和 v v v ,若边 < u , v > ∈ E ( G ) <u,v>∈E(G) <u,v>∈E(G) ,则 u u u 在线性序列中出现在 v v v 之前。
针对有向无环图,有向无环图一定存在拓扑序列,故有向无环图可以成为拓扑图。
一个有向无环图一定存在一个入度为0的点
无向图和有环图都没有拓扑排序

模板题:AcWing 848.有向图的拓扑序列
思路:每次只向队列里面加入入度为0的点,然后每次取出队头,再弹出对头,把队头点所连的边的入度都-1,如果出现了新的入度为0的点,就再加到队列里面,直到队列为空。最后判断加入的点的个数是否等于总的点的个数

核心AC代码:

邻接表存图

int e[MAXN],ne[MAXN],h[MAXN],idx;
void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}

入队操作(和BFS差不多,拓扑排序就是BFS的一个应用)

int d[MAXN],ans[MAXN],n;

bool topSort()
{
    queue<int>Q;
    int num=0;
    for(int i=1;i<=n;++i)//首先把所有入度为零的点入队
        if(!d[i])
        {
            Q.push(i);
            ans[++num]=i;
        }
    
    while(Q.size())
    {
        int t=Q.front();//取出队头元素
        Q.pop();//弹出队头元素
        
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            --d[j];//将邻边的入度都减一,因为队头这个点已经被弹出了
            if(!d[j])//出现了新的入度为0的点
            {
                Q.push(j);//把新的入度为0的点入队
                ans[++num]=j;
            }
        }
    }
    
    return num==n;
}

拓扑排序的另一道模板题:LeetCode 2050.并行课程

标签:int,拓扑,入度,更新,环图,MAXN,排序
来源: https://blog.csdn.net/weixin_54209457/article/details/121137193