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

    一个问题

    我们都知道在很多学校,有着许多的修学科目,但是这些科目却要有先后关系。比如,你要先学习**高等数学**,才可以报**计算机科学**等

    现在有一个人把报名学科的先后条件给你,让你找一个合理的方案,使得能够按你的顺序一次性学完整个任务

    什么意思

    意思是,有很多科目都有先修课程,你要先学完那个先修课程,才可以学这个课程;当然,那个先修课程可能还有自己的先修课程

    怎么解决

    很多人都知道,我们需要先找到第一个可以学的科目,等到学完以后再看看有没有学科可以学了,以此类推,直到学完为止

    那么,这种算法,叫做拓扑排序 (topsort)

    ——————————————分割线————————————————

    什么是拓扑排序

    在一个有向无环图里面,每一个点有入边或出边,问怎样才可以标记到一个点时,它的前驱全部都标记过

    最终按照这种顺序排列下来的一条线性表,就是拓扑序列

    拓扑排序算法

    就像我们上面的例子,你要先把先修学科全部学完,才可以学这一个科目

    那我们应该怎么样才能找到第一个可以学习的学科呢?

    肯定是找到一个没有先修课程的学科吧

    那么,拓扑排序也是一样的,如果这个点的入度为 0,那么代表着这个点**没有前驱**,所以可以直接标记

    那么,学完了这个科目,所有以这个科目为先修课的科目均可以进行学习

    所以在算法中,每次标记结束后,要删除连接它的所有出边

    当然,剩余的点的入度也要随着边的删除而改变

    下面给出一个例子

    3 3    //三个顶点、三条边
    3 1    //一的前驱为三
    1 2    //二的前驱为一
    3 2    //二的前驱为三



    第一步,确定每个点的入度

    一号点入度为 1,二号点为 2,三号点为 0

    第二步,从三号点开始

    标记三号点,因为从三号点分别有一条通向一号点、二号点的边,所以把一号、二号点的入度分别减一

    第三步,检查每个点入度

    发现一号点入度为 0 ,所以把一号点进行标记

    因为有一条一号点到二号点的边,所以二号点的入度减一

    第四步,继续检查每一个点入度

    发现只有二号点了,所以标记二号点,排序结束

    所以,最终答案是 3--1--2

  • 相关阅读:
    64位平台支持大于2 GB大小的数组
    NET Framework 4.5新特性 数据库的连接加密保护。
    永无止境之网站的伸缩性架构
    ASP.NET MVC IOC 之Ninject攻略
    C# 中几个小“陷阱”
    AngularJS的依赖注入方式
    JVM内存配置详解(转)
    StringBuilder、StringBuffer和String三者的联系和区别(转)
    Java线程的生命周期(转)
    Java程序员须知的七个日志管理工具(转)
  • 原文地址:https://www.cnblogs.com/zengpeichen/p/10942848.html
Copyright © 2011-2022 走看看