拓扑排序的定义 简单来说就是给你一个图写出一个序列 图中如果a通向b 那么序列中A必须排在B前面
拓扑排序可能有很多结果 必须是有向无环图 可以利用拓扑排序来判定环的存在 当然也可以用神奇的SPFA 但是拓扑排序时间复杂度很低 只有O(V+E)
基本实现思路是 每次取出入度为0的点 然后删除与它相连的边 直到没有边 如果还有边但是找不到入度为0的点 说明有环
学习这个算法联系了两道题目 很经典很单纯 但是一般没有OJ有评测 奖金这道题目在福州大学OJ和中山大学萌萌哒Sicily上找到了评测(为什么要叫西西里呢?)
先放题目:
家谱树
【题目描述】
有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输入一个序列,使得每个人的后辈都比那个人后列出。
【输入】
第一行一个整数(1<=N<=100),表示家族的人数。
接下来N行,第I行表示第I个人的儿子。
每行最后是0表示描述完毕。
【输出】
输出一个序列,使得每个人的后辈都比那个人后列出。
如果有多解输出任意一解。
【输入样例】
5
0
4 5 1 0
1 0
5 3
0
3 0
【输出样例】
2 4 5 3 1
这道题目显然只需要一次拓扑排序 输出任意一个序列就可以了 不要求输出结果而是序列 因此要在过程中数组保存出队的元素 另外这道题目没有环
放代码:
普通循环的代码
、
用了STL队列的代码 更加方便易懂
这道题目有环,要求输出结果而不是过程,因此解唯一。采用分层处理的办法,对于每一个奖金级别集中计算。代码注释说的很清楚,此处不再赘述。
这个思路参考了黄学长的代码,但是他的代码是错误的,我已经在他的博客中指正了。
但是仍有一个疑问,本代码在Sicily测得AC,福州大学WA了 所以本代码可能也有一定问题
尝试写了STL队列版 但是时间关系没有写完 而且本题queue实现有些困难 如果成功了之后补上
上代码
最后补充一下 几个很好的将拓扑排序的文章:
http://blog.csdn.net/dm_vincent/article/details/7714519 这个讲的有点高深,有兴趣的可以看一下
http://blog.csdn.net/liwen_7/article/details/7298736 浅显地介绍了原理
http://www.tyut.edu.cn/kecheng1/site01/suanfayanshi/topological_sort.asp 太原理工的精品课演示 有助于理解
其实所有博客都不如自己理解了最好···
努力努力向Tarjan进发!!!
——烟敛寒林簇,画屏展;天际遥山小,黛眉浅。
【日常学习】【拓扑排序】家谱树&FZU1483 Sicily1424 奖金 题解
原文:http://blog.csdn.net/ametake/article/details/45956159