<数据结构>拓扑排序
有向无环图
有向无环图(Directed Acycilc Graph, DAG):从任意顶点出发都无法回到自身的有向图。

拓扑排序
定义
任一两个顶点u,v间,如果存在边u->v,则排序后u一定在v前面。
问题导入

上图表示了数学课程间的相互关系,图的每个结点表示一门课程,每条有向边u->v表示“u是v的先导课程”(即上完u才能上v)的关系。
不难发现,如果要把上面所有课程排成课程顺序,保证在学习一门课程时,它的先导课程都已经全部学完,如果两门课程之间没有先导关系则排序任意。那么这一过程就可以抽象为拓扑排序。拓扑排序的序列不唯一。

注意: 很显然,拓扑排序只有在有向无环图中才能成功。如果图中有环,就不可能满足拓扑排序的定义,比如在上例中,数学分析是计算方法的先导,计算方法是高等几何的先导,但如果高等几何又是数学分析的先导,那整个课程不就乱套了。
算法实现
过程抽象:不断抽出入度为0的结点
- 定义一个队列Q,把所有入度为0的结点全部入队
- 取出队首结点,输出。 然后删去从它出发的所边, 并令这些边达到的顶点的入度减1。 如果某个顶点入度变为0,则入队。
- 重复2操作,直到队列为空。 队列为空时,若如果队的结点恰好为顶点数N,说明拓扑排序成功;否则,拓扑排序失败,图中有环。
代码实现
#include<stdio.h>
#include<queue> //用stl库中的queue实现队列
#include<vector>
using namespace std;
const int MAXV = 100;
vector<int> G[MAXV]; //邻接表实现图G
int n,m,inDegree[MAXV];//顶点数,入度
//拓扑排序
bool topologicalSort(){
int num = 0;
queue<int> q;
for(int i = 0; i<n; i++){
if(inDegree[i] == 0){
q.push(i); //将所有入度为0的顶点入队
}
}
while(!q.empty()){
int u = q.front(); //取队首顶点u
// printf("%d ", u); //此处可输出顶点,作为拓扑序列中的顶点
q.pop();
for(int i = 0; i < G[u].size(); i++){
int v = G[u][i]; //u的后继结点v
inDegree[v]--; //顶点v的入度-1
if(inDegree[v] == 0){ //顶点v的入度为0,则入队
q.push(v);
}
}
G[u].clear(); //清空所有边的出边,如无必要可不写
num++; //加入拓扑序列的顶点数+1
}
if(num == n) return true; //加入拓扑序列的顶点数为n,说明拓扑排序成功
else return false; //加入拓扑排序的顶点数小于n,说明拓扑排序失败
}
用途
- 进行拓扑排序
- 判断一个有向图中是否有环
<数据结构>拓扑排序的更多相关文章
- 拓扑排序<反向拓扑+有向环的判断>
题目链接 #include <set> #include <map> #include <cmath> #include <queue> #includ ...
- ACM/ICPC 之 拓扑排序-反向(POJ3687)
难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重 ...
- HDU2647(拓扑排序+反向建图)
题意不说了,说下思路. 给出的关系是a要求的工资要比b的工资多,因为尽可能的让老板少付钱,那么a的工资就是b的工资+1.能够确定关系为a>b,依据拓扑排序建边的原则是把"小于" ...
- HDU 4857 逃生 【拓扑排序+反向建图+优先队列】
逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- HDU 2647 Reward 【拓扑排序反向建图+队列】
题目 Reward Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to d ...
- hdu 4857 逆向拓扑排序+反向输出
/*一组测试实例 4 4 2 3 1 2 4 */ #include<stdio.h> #include<string.h> #include<queue> usi ...
- hdoj--4857--逃生(拓扑排序+反向建图)
逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submiss ...
- [bzoj3887][Usaco2015 Jan]Grass Cownoisseur_trajan_拓扑排序_拓扑序dp
[Usaco2015 Jan]Grass Cownoisseur 题目大意:给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在 ...
- POJ 1094 Sorting It All Out (拓扑排序,判断序列是否唯一,图是否有环)
题意:给出n个字符,m对关系,让你输出三种情况: 1.若到第k行时,能判断出唯一的拓扑序列,则输出: Sorted sequence determined after k re ...
- 大数据工作流任务调度--有向无环图(DAG)之拓扑排序
点击上方蓝字关注DolphinScheduler(海豚调度) |作者:代立冬 |编辑:闫利帅 回顾基础知识: 图的遍历 图的遍历是指从图中的某一个顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点 ...
随机推荐
- pyqt5的下拉菜单,可以进行输入文字
- mystar01 nodejs MVC 公共CSS,JS设置
mystar01 nodejs MVC gulp 项目搭建 config/express.js中定义别名 //将下载的第三方库添加到静态资源路径当中,方便访问 app.use('/jquery', e ...
- fastjson过滤多余字段
/** * Description:过滤实体中的字段 * @param src 需要过滤的对象,如 list,entity * @param clazz 实体的class ...
- [项目总结]怎么获取TextView行数,为什么TextView获取行数为0?
1 final TextView textView = new TextView(this); 2 ViewTreeObserver viewTreeObserver = textView.getVi ...
- GO 定时器NewTimer、NewTicker使用
package main import ( "fmt" "sync" "time" ) /** *ticker只要定义完成,从此刻开始计时, ...
- Can namespaces be nested in C++?
In C++, namespaces can be nested, and resolution of namespace variables is hierarchical. For example ...
- 【Linux】【Services】【Disks】zfs
1. 简介: 据说zfs有去除重复数据的功能,无良人士继续要求吧samba共享盘使用的centos7上自带的xfs改成zfs,并且开启去重功能.samba配置见 http://www.cnblogs. ...
- [PROC FREQ] 单组率置信区间的计算
本文链接:https://www.cnblogs.com/snoopy1866/p/15674999.html 利用PROC FREQ过程中的binomial语句可以很方便地计算单组率置信区间,SAS ...
- 云原生应用管理,像管理手机APP一样管理企业应用
我们在使用智能手机的时候,手机APP从应用市场一键安装,安装好即点即用,当有新版本一键升级,如果不想用了长按图标删除,整个过程非常简单,小朋友都能熟练掌握.而对于企业应用,由于结构复杂.可用性要求高. ...
- 《手把手教你》系列技巧篇(五十)-java+ selenium自动化测试-字符串操作-上篇(详解教程)
1.简介 自动化测试中进行断言的时候,我们可能经常遇到的场景.从一个字符串中找出一组数字或者其中的某些关键字,而不是将这一串字符串作为结果进行断言.这个时候就需要我们对字符串进行操作,宏哥这里介绍两种 ...