<数据结构>拓扑排序
有向无环图
有向无环图(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(海豚调度) |作者:代立冬 |编辑:闫利帅 回顾基础知识: 图的遍历 图的遍历是指从图中的某一个顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点 ...
随机推荐
- 从源码看RequestMappingHandlerMapping的注册与发现
1.问题的产生 日常开发中,大多数的API层中@Controller注解和@RequestMapping注解都会被使用在其中,但是为什么标注了@Controller和@RequestMapping注解 ...
- C++11的auto自动推导类型
auto是C++11的类型推导关键字,很强大 例程看一下它的用法 #include<vector> #include<algorithm> #include<functi ...
- Linux基础命令---wget下载工具
wget wget是一个免费的文件下载工具,可以从指定的URL下载文件到本地主机.它支持HTTP和FTP协议,经常用来抓取大量的网页文件. 此命令的适用范围:RedHat.RHEL.Ubuntu.Ce ...
- Dubbo中CompletableFuture异步调用
使用Future实现异步调用,对于无需获取返回值的操作来说不存在问题,但消费者若需要获取到最终的异步执行结果,则会出现问题:消费者在使用Future的get()方法获取返回值时被阻塞.为了解决这个问题 ...
- 关于UML类图方面的问题(连载)
UML类图符号:类中属性的可见性主要包括公有(public).私有(Private)和受保护(Protected).在UML中,公有类型的用"+"表达,私有类型用"-&q ...
- Innodb Cluster集群部署配置
目录 一.简介 二.环境声明 三.部署 安装(均操作) 配置(均操作) 开启group_replication(均操作) 启动group_replication 创建集群(在mysql-1执行) 创建 ...
- Jenkins视图管理
目录 一.简介 二.视图维护 创建视图 将项目加入视图中 三.状态图标变绿 四.看板 一.简介 在现在的编程中,公司往往采用的是模块化的编程方式,也就是说将一个项目拆分成许多模块,每个小项目组往往只负 ...
- malloc实现
任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放 掉.但是,许多程序员对malloc背后的事情并不熟悉,许多人甚 ...
- JS 双向数据绑定、单项数据绑定
简单的双向数据绑定 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- [BUUCTF]PWN——hitcontraining_magicheap
hitcontraining_magicheap 附件 步骤: 例行检查,64位程序,开启了nx和canary 本地试运行一下,经典的堆的菜单 64位ida载入,检索程序里的字符串的时候发现了后门 m ...