拓扑排序(Topological Order)UVa10305 Ordering Tasks
2016/5/19 17:39:07
拓扑排序,是对有向无环图(Directed Acylic Graph , DAG )进行的一种操作,这种操作是将DAG中的所有顶点排成一个线性序列,使得图中的任意一对顶点u,v满足如下条件:
若边(u,v)∈E(G),则在最终的线性序列中出现在v的前面
好了,说人话:拓扑排序的应用常常和AOV网相联系,在一个大型的工程中,某些项目不是独立于其他项目的,这意味着这种非独立的项目的完成必须依赖与其它项目的完成而完成,不妨记为u,v,则若边(u,v)∈E(G),代表着必须在项目u完成后,v才能完成。
这样,拓扑排序就可以表示一个工程的进度安排,这也样也更加方便我们理解为什么一个图如果有环,就一定不存在拓扑排序:因为这相当于在工程中你不停的重复做同一个项目,工程变成一个项目的循环,自然不存在拓扑排序。
当然,拓扑排序往往不会只有一种,通过DFS,我们可以求得拓扑排序。
拓扑排序的思路简述如下:
- 状态标记:共三种,-1表示访问中,0表示未访问,1表示已访问,由数组c保存
- dfs终止的判别条件:如果存在环,则不存在,退出;反之把当前结点加入拓扑排序的首部(线性序列的当前第一个位置,随着排序的进行,这个位置会不断前移)
- 通过topo数组记录拓扑排序
这里解释一下书上的问题:为什么访问完一个节点就把当前结点加入到拓扑排序首部?
答:因为由拓扑排序的性质可知,在DAG中,不妨任取从u顶点出发进行DFS,遇到v顶点,在最终的拓扑排序中始终应满足u在v之前,而根据DFS满足栈的FIFO性质可知,顶点v会先进入拓扑序列,顶点u后进入拓扑序列,因此,如果我们想要顺序获取拓扑序列,就应该将当前顶点(u)加入到拓扑排序的首部。当然,我们也可以通过模拟栈的FIFO特性,通过弹栈将逆序的拓扑序列变为顺序,但是这样无疑增加的操作的步骤,本质上是一样的。
接下来给出拓扑排序的代码:(图通过邻接矩阵存储)
#include<cstdio>
#include<cstring>
const int maxn=;
int n,m,u,v,t,topo[maxn],G[maxn][maxn],c[maxn];
//DFS
bool dfs(int u){
c[u]=-;//正在访问中
for(int i=;i<n;i++)if(G[u][i]){
if(c[i]<)return false;//存在环,退出
if(!c[i]&&!dfs(i))return false;//i没访问过且访问后发现有环,退出
}
c[u]=;topo[--t]=u;//u顶点访问完毕,修改状态,加入拓扑序列首部
return true;
}
//topological ordering
bool toposort(){
t=n;
memset(c,,sizeof(c));
for(int i=;i<n;i++)
if(!dfs(i))return false;
return true;
}
好了,介绍完拓扑排序,照例是大餐,算法和OJ搭配食用,味道更棒哦~
传送门:
UVa:10305 Ordering Tasks https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=838&page=show_problem&problem=1246
这是一道非常简单的拓扑排序,由题意我们可以知道,我们无需判断环的存在,因此代码简洁了不少,不过,题目中要求m和n同时为0时代表结束,一开始写成了m&&n,导致wa,后来发现应该是m||n
另外,在解题时,我用了栈来简化逆序操作,不然我还要计算一下输出序列的长度,再把dfs的结果加入到拓扑排序首部,想想就觉得很麻烦,还不如自己写一个栈来的简单~~~
几个地方在提交的时候要注意:
- index作为全局变量,在本地编译可过,UVa上会complication error,所以这里改用了pos来指代栈指针
- 注意这是多输入的题目,所以vis数组一定要用memset清空
- 本来想把结果输出的printf整合为一句话,但是发现这样的话,换行符无法输出,我想过一段时间找点资料,了解一下printf的实现,就应该能明白问题的根源了。
代码如下:
#include<cstdio>
#include<cstring>
#define N 100
int g[N+][N+],u,v,n,m,stack[N+],vis[N+],pos=;
void push(int x){
stack[pos++]=x;
}
int pop(){
return stack[--pos];
}
void dfs(int u){
vis[u]=-;//visting
for(int i=;i<=n;i++)if(g[u][i]&&!vis[i])
dfs(i);
push(u);vis[u]=;//visted
}
int main(){
while(scanf("%d%d",&n,&m)==&&(m||n)){//这里是m或n,与的话会wa,我离散数学要去面壁
while(m--){
scanf("%d%d",&u,&v);
g[u][v]=;
}
memset(vis,,sizeof(vis));//initialization
for(int i=;i<=n;i++)//topological sort
if(!vis[i])dfs(i);
while(pos){//print result
printf("%d",pop());
printf("%c",pos>?' ':'\n');//三目运算符真的很好用
}
}
}

这一篇就到这里啦~~~
拓扑排序(Topological Order)UVa10305 Ordering Tasks的更多相关文章
- 拓扑排序 (Topological Sorting)
拓扑排序(Topological Sorting) 一.拓扑排序 含义 构造AOV网络全部顶点的拓扑有序序列的运算称为拓扑排序(Topological Sorting). 在图论中,拓扑排序(Topo ...
- UVA-10305 Ordering Tasks (拓扑排序)
题目大意:给出n个点,m条关系,按关系的从小到大排序. 题目分析:拓扑排序的模板题,套模板. kahn算法: 伪代码: Kahn算法: 摘一段维基百科上关于Kahn算法的伪码描述: L← Empty ...
- UVA10305 Ordering Tasks (拓扑序列)
本文链接:http://www.cnblogs.com/Ash-ly/p/5398586.html 题意: 假设有N个变量,还有M个二元组(u, v),分别表示变量u 小于 v.那么.所有变量从小到大 ...
- LeetCode编程训练 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- 算法与数据结构基础 - 拓扑排序(Topological Sort)
拓扑排序基础 拓扑排序用于解决有向无环图(DAG,Directed Acyclic Graph)按依赖关系排线性序列问题,直白地说解决这样的问题:有一组数据,其中一些数据依赖其他,问能否按依赖关系排序 ...
- 拓扑排序 Topological Sort
2018-05-02 16:26:07 在计算机科学领域,有向图的拓扑排序或拓扑排序是其顶点的线性排序,使得对于从顶点u到顶点v的每个有向边uv,u在排序中都在v前.例如,图形的顶点可以表示要执行的任 ...
- 【数据结构与算法Python版学习笔记】图——拓扑排序 Topological Sort
概念 很多问题都可转化为图, 利用图算法解决 例如早餐吃薄煎饼的过程 制作松饼的难点在于知道先做哪一步.从图7-18可知,可以首先加热平底锅或者混合原材料.我们借助拓扑排序这种图算法来确定制作松饼的步 ...
- Uva10305 Ordering Tasks
John有n个任务,但是有些任务需要在做完另外一些任务后才能做. 输入 输入有多组数据,每组数据第一行有两个整数1 <= n <= 100 和 m.n是任务个数(标记为1到n),m两个任务 ...
- 拓扑排序(三)之 Java详解
前面分别介绍了拓扑排序的C和C++实现,本文通过Java实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处 ...
随机推荐
- android中常见的命名及其特点详解
Paseal命名法 Paseal命名法特点:String MyName-DelphiInt MyAge每个单词首字母大写 Camel命名法 Camel(驼峰的意思)命名法特点:String myNam ...
- BZOJ4563 HAOI2016放棋子(高精度)
没看清题还以为是要求数最大匹配数量……注意到任意障碍不在同一行同一列,且恰好有n个障碍,不妨通过交换列使得第i行第i列均有障碍.那么就是个错排了.居然wa了一发简直没救. #include<io ...
- 【题解】HAOI2007分割矩阵
水题盛宴啦啦啦……做起来真的极其舒服,比某些毒瘤题好太多了…… 数据范围极小 --> 状压 / 搜索 / 高维度dp:观察要求的均方差,开始考虑是不是能够换一下式子.我们用\(a_{x}\)来表 ...
- [CF912B]New Year's Eve
题意:在1~n中选不超过m个数,求其异或最大值 题解:经过找规律发现如果m为1,输出n,不然输出最小的不超过n的2^k-1 C++ Code: #include<cstdio> using ...
- Angular 遍历循环数组
var app = angular.module('Mywind',['ui.router']) app.controller('Myautumn',function($scope,$http,$fi ...
- Unescape JavaScript's escape() using C#
js里面的 unescape escape 对应C#里面 var unescapedString = Microsoft.JScript.GlobalObject.unescape(yourEscap ...
- 谈一谈深度学习之semantic Segmentation
上一次发博客已经是9月份的事了....这段时间公司的事实在是多,有写博客的时间都拿去看paper了..正好春节回来写点东西,也正好对这段时间做一个总结. 首先当然还是好好说点这段时间的主要工作:语义分 ...
- [SCOI2007] 蜥蜴 (最大流)
[SCOI2007] 蜥蜴 题目背景 07四川省选 题目描述 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1 ...
- HDFS的xshell及dfsadmin命令
一. DFS:distributied file system 是一种允许文件通过网络在多台主机上风向的文件系统,可让多机器上的多用户分享文件和存储空间 二.HDFS的shell **切记后面加的 / ...
- JVM 性能排查 自己做的笔记
Live Memory 1.Class Tracker 展示类或包的实例个数与时间的关系.需要录制才可以看到. 1)可以添加指定的类或包. 2.All Objects 查看所有类的实例个数和大小.可以 ...