zoukankan      html  css  js  c++  java
  • 拓扑排序

    1.定义

    在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

      1.每个顶点出现且只出现一次。
      2.若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。

    2.应用

    在整个工程中,有些子工程(活动)必须在其它有关子工程完成之后才能开始,为了形象地反映出整个工程中各个子工程(活动)之间的先后关系,可用一个有向图来表示,图中的顶点代表活动(子工程),图中的有向边代表活动的先后关系,即有向边的起点的活动是终点活动的前序活动,只有当起点活动完成之后,其终点活动才能进行。通常,我们把图称做顶点活动网(Activity On Vertex network),简称AOV网。

    一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行

    3.实现

    由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
    (1) 选择一个入度为0的顶点并输出之;
    (2) 从网中删除此顶点及所有出边。
    循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。

    4.训练

    (附上某大佬的博客: https://dylanli-hang.github.io/2019/07/26/拓扑排序/ )
    最基础的模板:
    UVA10305 给任务排序 Ordering Tasks
    https://www.luogu.org/problem/UVA10305
    没有账号的同学去: https://vjudge.net/problem/UVA-10305 提交

    需要处理一点的拓扑排序:
    P1038神经网络
    https://www.luogu.org/problem/P1038

    拓扑排序保证无后效性+简单动规:
    P1137 旅行计划
    https://www.luogu.org/problem/P1137

    可以用拓扑排序解决的:
    P1983 车站分级
    https://www.luogu.org/problem/P1983

    模板题 相当直接的做法:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define sizen 120
    using namespace std;
    int n,m;
    int map[sizen][sizen],degree[sizen];
    bool vis[sizen];
    
    //若遇到入度为0的点,删除所有以该点为起点的边
    void dfs(int i){ 
        for(int j=1;j<=n;j++) 
            if(map[i][j]){
                map[i][j] = 0;
                degree[j]--;
                if(degree[j] == 0)printf("%d ",j),vis[j] = 1,dfs(j);
            }
        return;
    }
    
    int main(){
    
        int u,v;
        while(cin>>n>>m){
            if(m == 0 && n == 0)break;
            memset(map,0,sizeof(map));
            memset(degree,0,sizeof(degree));
            memset(vis,0,sizeof(vis));
            for(int i=1;i<=m;i++){
                scanf("%d%d",&u,&v);
                map[u][v] = 1;
            }
            
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++)
                    if(map[i][j])degree[j]++;
            }
            
            for(int i=1;i<=n;i++)
                if(degree[i] == 0 && !vis[i]){
                    printf("%d ",i);
                    vis[i] = 1;
                    dfs(i);
                }
            printf("
    ");
        }
        
        return 0;
    } 
  • 相关阅读:
    JZ初中OJ 2266. 古代人的难题
    JZ初中OJ 1341. [南海2009初中] water
    JZ初中OJ 1340. [南海2009初中] jumpcow
    JZ初中OJ 2000. [2015.8.6普及组模拟赛] Leo搭积木
    JZ初中OJ 1999.[2015.8.6普及组模拟赛] Wexley接苹果
    Unity Android平台下插件/SDK开发通用流程
    UNITY接入支付宝(未测试可行)
    Unity接入支付宝(免写安卓代码,使用JAR方式)
    Unity之多态
    unity与android交互(1)与(2)网友的整理
  • 原文地址:https://www.cnblogs.com/Cindy-Chan/p/11255606.html
Copyright © 2011-2022 走看看