• 浅谈 拓扑排序


    我是什么时候想到要学拓扑排序的呢?

    在一次模考的时候,有这样一道题,叫做食物链,我是写了记忆化搜索的,然而全场都写了拓扑板子

    后来发现我居然不会这么基础的算法,有点慌

    下面进入正题


    拓扑排序是针对一些特殊问题的,类似于在完成某一件是之前,有必要条件,要先完成另外的一些任务

    只有有向无环图才有拓扑排序,这就关系到了定义

    拓扑排序是先排入度为零的点,然后把所有的与之有关的边都删掉,这时就又会有一些如度为零的点出现

    然以后循环上述操作

    这就是拓扑排序的基本概念

    还是举个例子吧

    如图:

    我们发现1的如度为零

    所以先把1删掉,把与1有关的边删掉

    然后就发现2的入度变成了零

    然后会重复上述操作

    得到了这个图的与拓扑排序:1   2   3   4   5

    下面给出代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    inline int min(int a,int b){return a<b?a:b;}
    inline int max(int a,int b){return a>b?a:b;}
    inline int rd()
    {
        int x=0,f=1;
        char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    inline void write(int x)
    {
         if(x<0) putchar('-'),x=-x;
         if(x>9) write(x/10);
         putchar(x%10+'0');
    }
    int n,m;
    int head[100006],nxt[100006],to[100006];
    int in[100006];
    int total=0;
    void add(int x,int y){//邻接表存边 
        total++;
        in[y]++;
        to[total]=y;
        nxt[total]=head[x];
        head[x]=total;
        return ;
    }
    int tot=0;
    int s[100006];
    void topo(){
        for(int i=1;i<=n;i++) if(!in[i]) s[++tot]=i;//先找出已有的入度为零的点 
        for(int i=1;i<=tot;i++){
            for(int e=head[s[i]];e;e=nxt[e]){//删除与其相关的边 
                in[to[e]]--;
                if(!in[to[e]]) s[++tot]=to[e];//如果又出现入度为零的点,就入队 
            }
        }
        return ;
    }
    int main()
    {
        n=rd(),m=rd();
        for(int i=1;i<=m;i++){
            int x=rd(),y=rd();
            add(x,y);//有向图单向存边 
        }
        topo();
        for(int i=1;i<=n;i++) printf("%d
    ",s[i]);
        return 0;
    }

    可算是填了坑QAQ

    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    Java实现HttpClient发送GET、POST请求(https、http)
    解决.net core 3.1 json日期带T的问题
    Java验证身份证号码的格式
    c++20新特性concept
    位图
    Linux内核 hlist_head/hlist_node结构解析
    linux将c++程序制作成.deb
    应用程序或动态库中与加载的其他动态库的类或者函数重名问题
    vue props 属性值接受多个类型
    异步循环
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9716347.html
Copyright © 2020-2023  润新知