拓扑排序——杨子曰算法

拓扑排序——杨子曰算法

要知道,如果你要用c++打出拓扑排序的代码,你先要学会c++语法和拓扑排序的原理,你要学会c++语法你先要学会基本数学和计算机基础知识(←Are U sure?),你要学会拓扑排序的原理,你先要学会计算机基础知识和栈的使用,那现在让一个什么都不会的人学会拓扑,请输出任意一种合法方案


拓扑排序不像我们平时对数组排序那样,它是对一个有向图排序,↑就像上面那个↑,我们可以对这样的问题建一个图,从可以先选的,连向后选的,比方说:
选完1才能选2,3
选完3才能选7
选完7才能选2
选完2,4才能选5
选完5才能选6
我们就可以建这样一张图:
这里写图片描述
我觉得地球人一看就能明白
这里我们要知道一个东东——入度,就是指向这个点的边的数量
这样一来,我们每次都佛系地选一个入度为0的点,再把它连出去的边全部删掉(其实就是把连到的那个点的入度-1),你可以把入度为0的点放到一个栈里,每次弹出一个,然后不停重复,完事

用↑上面那个图↑,我们来举个栗子(←不是错别字)
首先我们发现,入度为0的点只有1,把它输出并删掉
这里写图片描述
这样2的入度-1, 3的入度-1
我们又发现3的入度为0,我们把3输出并删掉
这里写图片描述
所以7的入度-1,4的入度-1
噢,我们发现现在有两个点的入度都为零了,全部压倒栈里,随便选一个删掉,比如7
这里写图片描述
现在2和4,都可以选,佛系选了2
这里写图片描述
这时,我们发现只有4能选了,选上
这里写图片描述
这里写图片描述
我们得到了最终的序列:1,3,7,2,4,5,6
OK,完事
于 XJZX 507机房


c++代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn=50005,maxm=100005;

struct Edge{
    int next,to;
}edge[maxm*2];

int n,m,nedge=0,inc[maxn],head[maxn],stk[maxn];//inc时入度

void addedge(int a,int b){
    edge[nedge].to=b;
    edge[nedge].next=head[a];
    head[a]=nedge++;
}

int main(){
    memset(head,-1,sizeof(head));
    memset(inc,0,sizeof(inc));
    scanf("%d%d",&n,&m);
    while(m--){
        int a,b;
        scanf("%d%d",&a,&b);
        addedge(b,a);
        inc[a]++;
    }
    int top=0;
    for (int i=1;i<=n;i++){
        if (!inc[i]) stk[++top]=i;
    }
    while(top>0){
        int x=stk[top--];
        cout<<x<<' ';
        for (int i=head[x];i!=-1;i=edge[i].next){
            int v=edge[i].to;
            if (!--inc[v]) stk[++top]=v;
        }
    }
    return 0;
}

未经作者允许,严禁转载:https://blog.csdn.net/HenryYang2018/article/details/81041060

猜你喜欢

转载自blog.csdn.net/henryyang2018/article/details/81041060