【图】拓扑排序

参考CSDN拓扑排序的原理及Java实现

  拓扑排序C++实现

  拓扑排序百度百科

若不是上了学堂在线的数据结构课程,我估计今后不做技术的话,都接触不到图的拓扑排序这个概念了。先是看了百度百科的解释,拓扑排序现实中的应用是选课,即某些课程需要一些先修课程的学习后才适合上。比如数据结构的学习,是离散数学、编程语言,后者是前者的先修课程。

拓扑排序定义:将有向无环图DAG中的顶点以线性方式进行排序。即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面。

1.创建图;

2.将图中入度为0的顶点压入栈中;

3.将栈顶元素出栈,并将其邻接顶点的入度减1,若该邻接顶点的入度等于0,将该邻接顶点入栈;否则将边更新为栈顶元素的另一条边。

4.重复3,直至栈空。

一道关于OJ上的旅行商的问题,对图中可能通过的点的最大个数进行统计。实质是拓扑排序,但并不完全是排序,这里需要对一条通路上的顶点个数进行统计。

如图所示,1~6个村庄,但不是任意两个村庄之间都能相通,统计最长道路经过的村庄数,此时该结果为4.

以下是deadline截止前写的,但OJ提交后没有结果,只有一个compilation error编译错误的指示。codeblocks上测试了几个是通过的,或许还有错误吧,不过稍微能理解图的创建和拓扑排序了。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <iostream>
  4 #define MAX_VEX 1000001 //顶点
  5
  6 #define _Size 100000 //栈的大小
  7
  8 struct Stack{
  9     int *element;
 10     int top;
 11     int _size;
 12
 13     void initialStack(){
 14         element = new int[_Size];
 15         top = -1;
 16         _size = _Size;
 17     }
 18     void push(int x){
 19         element[++top] = x;
 20     }
 21     int pop(){
 22         return element[top--];
 23     }
 24 }S;
 25
 26
 27 typedef struct edgeNode {
 28     int adjvex;
 29    // int num;
 30     edgeNode *nextedge;
 31 }edgeNode;
 32
 33 typedef struct vexNode{
 34     int data;
 35     edgeNode *firstedge;
 36     int inDegree = 0; //入度初始为0
 37 }vexNode;
 38
 39 typedef struct vexList{
 40     vexNode vexlist[MAX_VEX];
 41     int vexnum, edgenum;
 42 }vexList;
 43
 44 void GraphList(vexList &G, int n, int m){
 45     G.edgenum = m;
 46     G.vexnum = n;
 47     for (int i = 1; i < n + 1; i++){
 48         G.vexlist[i].data = i; // 顶点从1~n;
 49         G.vexlist[i].firstedge = NULL;
 50
 51     }
 52     for (int i = 0; i < m ; i++){  // 有向边
 53         int from, to;
 54         scanf("%d %d", &from, &to);
 55         edgeNode *p = new edgeNode;
 56         p->adjvex = to;
 57         p->nextedge = G.vexlist[from].firstedge;
 58         G.vexlist[from].firstedge = p;
 59     }
 60 }
 61
 62 int Tsort(vexList &G){
 63    // Stack;
 64     S.initialStack();
 65     edgeNode *p;
 66     int cnt = 1;
 67     for (int i = 1; i < G.vexnum + 1; i++){
 68         p = G.vexlist[i].firstedge;
 69         while (p){
 70             G.vexlist[p->adjvex].inDegree++;
 71             //G.vexlist[i].firstedge->num++;
 72             p = p->nextedge;
 73         }
 74     }
 75     for (int i = 1; i < G.vexnum + 1; i++){
 76         if(G.vexlist[i].inDegree == 0){
 77             S.push(i);
 78         }
 79     }
 80     while (S.top != -1){
 81         int j = S.pop();
 82         //cnt++;
 83         p = G.vexlist[j].firstedge;
 84         while (p){
 85             G.vexlist[p->adjvex].inDegree--;
 86           //  G.vexlist[j].firstedge->num--;
 87             if (G.vexlist[p->adjvex].inDegree == 0 && p->nextedge == NULL){
 88                 S.push(p->adjvex);
 89                 cnt++;
 90             }
 91
 92             p = p->nextedge;
 93         }
 94     }
 95     return cnt;
 96 }
 97 vexList G;
 98 int main(){
 99     int n, m;
100     int cnt = 0;
101     scanf("%d %d", &n, &m);
102     GraphList(G, n, m);
103     cnt = Tsort(G);
104     printf("%d", Tsort(G));
105     return 0;
106 }
时间: 2024-08-10 23:18:43

【图】拓扑排序的相关文章

数据结构:图--拓扑排序

拓扑排序 拓扑排序 在实际应用中,有向图的边可以看做是顶点之间制约关系的描述.把顶点看作是一个个任务,则对于有向边<Vi,Vj>表明任务Vj的完成需等到任务Vi完成之后,也就是说任务Vi先于任务Vj完成.对于一个有向图,找出一个顶点序列,且序列满足:若顶点Vi和Vj之间有一条边<Vi,Vj>,则在此序列中顶点Vi必在顶点Vj之前.这样的一个序列就称为有向图的拓扑序列(topological order). 步骤 从有向图中选取一个没有前驱(入度为0)的顶点输出. 删除图中所有以它为

HDU4857——逃生(反向建图+拓扑排序)

逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一

算法系列之图--拓扑排序

本文介绍使用深度先搜索对向无环图(DAG)进行拓扑排序. 对于一个有向无环图G=(V,E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:如果G包含边(u,v)则结点u在拓扑排序中处于结点v的前面(若图G包含一个环路则不可能排出一个线性次序).可将图中的拓扑排序看成是将图的所有结点在一条水平线上排开,图中所有边都从左指向右. 给一个拓扑图如下示: 拓扑排序算法与DFS相似,但是在拓扑排序的过程中,每个结点都是后与其临接链表里的结点而放入Stack中. 具体代码如下示: 1 #i

CSU 1804: 有向无环图 拓扑排序 图论

1804: 有向无环图 Submit Page   Summary   Time Limit: 5 Sec     Memory Limit: 128 Mb     Submitted: 716     Solved: 298 Description Bobo 有一个 n 个点,m 条边的有向无环图(即对于任意点 v,不存在从点 v 开始.点 v 结束的路径). 为了方便,点用 1,2,-,n 编号. 设 count(x,y) 表示点 x 到点 y 不同的路径数量(规定 count(x,x)=0

图——拓扑排序(uva10305)

John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed. Input The input will consist of several instances of the problem. Each instance begins with

BZOJ 1565 NOI2009 植物大战僵尸 最大权闭合图+拓扑排序

题目大意:给定一个m*n的草坪,每块草坪上的植物有两个属性: 1.啃掉这个植物,获得收益x(可正可负) 2.保护(r,c)点的植物不被啃掉 任何一个点的植物存活时,它左侧的所有植物都无法被攻击 求最大收益 首先这个保护和被保护的关系就是最大权闭合图的连边关系 然后直接跑就行 然后我们就会发现没过样例0.0 原因当图出现环时,根据题意,环上的所有点都不能取(想象一个无冷却的食人花前面放一个坚果) 所以这题还要去掉环 由于环上的点不能取,所以所有指向环上的点的点都不能取 这个条件看起来不太好做,我们

hdu 4857 逆向建图+拓扑排序 ***

题意:糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行.现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一定有解. 链接:点我 题目

[POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]

题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是$O(n^2)$级别的,显然会挂 发现两条性质: 1.所有的限制条件中,给定的总点数不超过3e5个 2.是一个点比一段区间大 第二个条件决定了我们可以利用线段树优化建图,而第一个条件告诉了我们,本题的总边数应该是$sumk\astlog_2n$级别的 那么就做完了 注意拓扑排序的时候有个技巧,把连向

图-&gt;有向无环图-&gt;拓扑排序

文字描述 关于有向无环图的基础定义: 一个无环的有向图称为有向无环图,简称DAG图(directed acycline graph).DAG图是一类较有向树更一般的特殊有向图. 举个例子说明有向无环图的应用.假如有一个表达式: ((a+b)*(b*(c+d))+(c+d)*e)*((c+d)*e), 可以用之前讨论的二叉树来表示,也可以用有向无环图来表示,如下图.显然有向无环图实现了对相同子式的共享,从而比二叉树更节省空间. 关于拓扑排序的基础定义: 由某个集合上的一个偏序得到该集合上的一个全须

[算法小练][图][拓扑排序+深度优先搜索] 平板涂色问题

说在前面 本题是一道经典题目,多做经典题目可以节省很多学习时间,比如本题就包含了许多知识:回溯+剪枝+拓扑排序+深度优先搜索.[动态规划方法另作讨论] 关键代码 题: CE数码公司开发了一种名为自动涂色机(APM)的产品.它能用预定的颜色给一块由不同尺寸且互不覆盖的矩形构成的平板涂色. 为了涂色,APM需要使用一组刷子.每个刷子涂一种不同的颜色C.APM拿起一把有颜色C的刷子,并给所有颜色为C且符合下面限制的矩形涂色: 为了避免颜料渗漏使颜色混合,一个矩形只能在所有紧靠它上方的矩形涂色后,才能涂