拓扑排序是对DAG(有向无环图)上的节点进行排序,使得对于每一条有向边

都在
之前出现。简单地说,是在不破坏节点

先后顺序的前提下,把DAG拉成一条。如果以游戏中的科技树(虽然名字带树,其实常常不是树而只是DAG)举例,拓扑排序就是找到一种可能的点科技树的顺序

拓扑排序最经典的算法是Kahn算法。首先,先拿出所有入度为0的点排在前面,并在原图中将它们删除:

这时有些点的入度减少了,于是再拿出当前所有入度为0的点放在已经排序的序列后面,然后删除:

因为是有向无环图,而且删除操作不会产生环,所以每时每刻都一定存在入度为0的点,一定可以不断进行下去,直到所有点被删除。

以下是一个

的实现(
分别表示点数和边数),利用了队列:
// deg是入度,在存图的时候需要录入数据
// A是排序后的数组
int deg[MAXN], A[MAXN];
bool toposort(int n)
{int cnt = 0;queue<int> q;for (int i = 1; i <= n; ++i)if (deg[i] == 0)q.push(i);while (!q.empty()){int t = q.front();q.pop();A[cnt++] = t;for (auto to : edges[t]){deg[to]--;if (deg[to] == 0) // 出现了新的入度为0的点q.push(to);}}return cnt == n;
}

返回值为是否成功进行拓扑排序,也即是否存在环。也就是说拓扑排序是可以用来简单地判环的。有时会要求输出字典序最小的方案,这时把queue改成priority_queue即可,复杂度会多一个

这里有一道例题:

CF510C Fox And Names

Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: "Fox"). She heard a rumor: the authors list on the paper is always sorted in the lexicographical order.
After checking some examples, she found out that sometimes it wasn't true. On some papers authors' names weren't sorted in lexicographical order in normal sense. But it was always true that after some modification of the order of letters in alphabet, the order of authors becomes lexicographical!
She wants to know, if there exists an order of letters in Latin alphabet such that the names on the paper she is submitting are following in the lexicographical order. If so, you should find out any such order.Lexicographical order is defined in following way. When we compare

and
, first we find the leftmost position with differing characters:
. If there is no such position (i. e.
is a prefix of
or vice versa) the shortest string is less. Otherwise, we compare characters
and
according to their order in alphabet.

Input
The first line contains an integer

(
): number of names.

Each of the following n lines contain one string

(
), the
-th name. Each name contains only lowercase Latin letters. All names are different.

Output
If there exists such order of letters that the given names are sorted lexicographically, output any such order as a permutation of characters 'a'–'z' (i. e. first output the first letter of the modified alphabet, then the second, and so on).
Otherwise output a single word "Impossible" (without quotes).Examplesinput
3
rivest
shamir
adlemanoutput
bcdefghijklmnopqrsatuvwxyz

简单地说,就是给出一张名字的列表,要找到一张字母表使得这张人名的列表是按字典序排列的。

通过对相邻的两个名字间进行比较,可以得到

个关系(如样例中
),它们可以构成一张图,而最后线性的字母表也必须要满足这些关系。很明显,如果这张图存在环,必然是无解的;而如果无环,那么拓扑排序即可得到结果。

Pecco:算法学习笔记(目录)​zhuanlan.zhihu.com

输出dag的所有拓扑排序序列_算法学习笔记(53): 拓扑排序相关推荐

  1. 两个字符串的最长公共子序列长度_算法学习笔记(58): 最长公共子序列

    (为什么都更了这么多篇笔记了,这时候才讲这么基础的内容呢?因为我本来以为LCS这种简单的DP不用讲的,结果CF不久前考了LCS的变式,然后我发现由于自己对LCS一点都不熟,居然写不出来 ,于是决定还是 ...

  2. 9个元素换6次达到排序序列_全面讲解十大经典排序算法(Python实现)

    作者 | hustcc 链接 | https://github.com/hustcc/JS-Sorting-Algorith 排序算法是<数据结构与算法>中最基本的算法之一.排序算法可以分 ...

  3. 【算法学习笔记】83.排序辅助 动态规划 SJTU OJ 1282 修路

    此题倒是能用贪心骗点分... 其实对于每一个位置 , 我们知道最后的改善结果一定是原数列中的数 . (因为要尽量减少消耗, 可以考虑减小至和相邻的相同) 有了这个结论之后, 我们就考虑用dp来做这件事 ...

  4. 线性求逆元模板_算法学习笔记(9):逆元

    https://zhuanlan.zhihu.com/p/105467597在数论中,如果 ,我们就说 和 在模 意义下互为乘法逆元,记作 . 逆元有什么用呢?我们常常遇到一些题目要求结果对一个大质数 ...

  5. 大顶堆删除最大值_算法学习笔记(47): 二叉堆

    堆(Heap)是一类数据结构,它们拥有树状结构,且能够保证父节点比子节点大(或小).当根节点保存堆中最大值时,称为大根堆:反之,则称为小根堆. 二叉堆(Binary Heap)是最简单.常用的堆,是一 ...

  6. c++ 链表_算法学习笔记 - 链表 - 单链表的粗糙实现

    常用的链表有单链表.双链表.循环链表. 概念看得再多,理解得再多,也不一定能够写得出来.所以动动手,多练习才是提升能力的关键. 有朋友留言说道:建议大家在实现之前的思考时间不要太长.一是先用自己能想到 ...

  7. l2-004 这是二叉搜索树吗?_算法学习笔记(45): 二叉搜索树

    二叉搜索树(Binary Search Tree, BST)是一种常用的数据结构,在理想情况下,它可以以 的复杂度完成一系列修改和查询,包括: 插入一个数 删除一个数 查询某数的排名(排名定义为比该数 ...

  8. 狄利克雷卷积_算法学习笔记(35): 狄利克雷卷积

    这篇笔记完全是数学内容,但它是之后一些算法的基础. 所谓狄利克雷卷积,是定义在数论函数( 的函数)间的一种二元运算,可这样定义: 也常常等价地写作: 为了之后讨论方便,先定义一些常用的数论函数的符号: ...

  9. 《Algorithm算法》笔记:元素排序(2)——希尔排序

    <Algorithm算法>笔记:元素排序(2)--希尔排序 Algorithm算法笔记元素排序2希尔排序 希尔排序思想 为什么是插入排序 h的确定方法 希尔排序的特点 代码 有关排序的介绍 ...

最新文章

  1. dump mysql_mysql/mariadb知识点总结(28):mysql备份工具之mysqldump
  2. IT人不要一直做技术[转载]
  3. c_str()和strcasecmp
  4. JQuery中$.ajax()方法参数详解(转)
  5. ubuntu16.04 安装ros
  6. navicat 怎么调试存储过程_Mysql调试存储过程最简单的方法
  7. java 证书公钥 私钥_ssl - 在Java Key中导入私钥/公钥证书对
  8. 计算机课程布置作业,计算机是如何工作的(教案)
  9. 小猪佩奇(python)
  10. 《现代操作系统(中文第四版)》课后习题答案 第四章 文件系统
  11. 使用Word制作签名电子版
  12. 洛谷P3376-网络流
  13. 软件即服务已经过时 硬件即服务促成云计算
  14. 从“靠山吃山,靠水吃水”到守望“绿水青山”
  15. 【科创人】快狗打车CTO沈剑:努力不会背叛,承担社会责任的企业胜算高一点点...
  16. Python语言基础编程
  17. 谷粒学院订单管理 server-order 模块
  18. 围绕边框宽度的html,设置围绕表格的边框宽度的HTML代码是?
  19. 用u盘把红旗linux操作系统安装到电脑硬盘c:,把系统装进U盘的详细步骤
  20. 排队论(Queuing theory)简介

热门文章

  1. Mysql数据库小命令
  2. 红黑树 平衡二叉搜索树_红黑树:自我平衡的二叉搜索树,并举例说明
  3. 黑猫警长 stl_如何使用当地警长保护您的信息
  4. java final char_java基本数据类型总结 类型转换 final关键字的用法
  5. 设置maven的阿里云代理
  6. 关于7z结尾的压缩包操作系统
  7. Python初学者的自我修养,找到自己的方向
  8. 一篇好的技术博文,快速让你通俗理解Python闭包!
  9. Python网络编程——使用TCP方式传输文件
  10. 游戏cg提取工具_记蒼の彼方のフォーリズム の CG提取