算法总结之拓扑排序

拓扑排序

1.一般应用

      拓扑排序常用来确定一个依赖关系集中,事物发生的顺序。例如,在日常工作中,可能会将项目拆分成A、B、C、D四个子部分来完成,但A依赖于B和D,C依赖于D。为了计算这个项目进行的顺序,可对这个关系集进行拓扑排序,得出一个线性的序列,则排在前面的任务就是需要先完成的任务。

2.实现的基本方法

  (1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.

  (2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.

  (3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

3.C++版本实现

 1 /*以邻接矩阵Edge[A][B]=N存放图信息:A指向B,权值为N*/
 2 /*假设不相连的边的Edge==INT_MAX*/
 3 void Topo()
 4 {
 5     sort(Edge+1,Edge+N+1);
 6     for (int i=1; i<=N; i++)
 7     {
 8         int j;
 9         for (j=1; j<=N; i++)  //vis为标记数组,标记是否已经存在在Topo数组中
10             if (!vis[j]&&!in[j]) //in数组表示的下标顶点的入度
11             {
12                 Topo[i]=j;
13                 vis[j]=1;
14                 break;
15             }
16         for (int k=1;k<=N;k++) //将与j点相连的顶点的入度刷新
17             if (Edge[j][k]!=INT_MAX)
18                 in[k]--;
19     }
20 }

4.反向建图

  拓扑排序并不一定唯一,有时会要求顶点数值大的尽量在前,这个时候应该反向建图,再进行拓扑排序,来保证更多小数值顶点在后面。(贪心思想?)

  Eg:HDU 4857 POJ 3687(反向建图+拓扑排序)

5.优化

  拓扑排序每次选择一个顶点进入序列后,要更新所有与这个顶点相连的顶点的入度。而上面的代码全是把所有的顶点都遍历了一边。

  这里可以使用邻接表或者链式前向星这一类数据结构,来记录图的信息,可以做到只遍历与该顶点相连的顶点

6.优先队列实现

 1 /*优先队列+邻接表实现拓扑排序*/
 2 void Topo()
 3 {
 4     priority_queue<int> que;
 5     for (int i=1; i<=N; i++) //将入度为零的顶点压入队列
 6         if (dis[i]==0)
 7             que.push(i);
 8     int p=N+1;
 9     while (!que.empty())
10     {
11         int tmp=que.top();
12         que.pop();
13         topo[--p]=tmp;     //存入topo数组
14         int z=first[tmp];
15         while (z!=-1)       //邻接表遍历与tmp相连的顶点
16         {
17             dis[end[z]]--; //入度减一
18             if(!dis[end[z]]) que.push(end[z]);
19             z=next[z];
20         }
21     }
22 }

算法总结之拓扑排序

时间: 2024-07-29 20:14:19

算法总结之拓扑排序的相关文章

数据结构和算法17 之拓扑排序

本文为博主原创文章,转载请注明出处:http://blog.csdn.net/eson_15/article/details/51194219 这一节我们学习一个新的排序算法,准确的来说,应该叫"有向图的拓扑排序".所谓有向图,就是A->B,但是B不能到A.与无向图的区别是,它的边在邻接矩阵里只有一项(友情提示:如果对图这种数据结构部不太了解的话,可以先看一下这篇博文:数据结构和算法之 无向图.因为拓扑排序是基于图这种数据结构的). 有向图的邻接矩阵如下表所示: A B C A

算法笔记_023:拓扑排序(Java)

目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进行排序.即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面. 2 解决方案 2.1 基于减治法实现 实现原理:不断地做这样一件事,在余下的有向图中求取一个源(source)(PS:定义入度为0的顶点为有向图的源),它是一个没有输入边的顶点,然后把它和所有从它出发

数据结构 - 拓扑排序

应用背景 学生选修课程问题 顶点--表示课程 有向弧--表示先决条件,若课程i是课程j的先决条件,则图中有弧(i,j) 学生应按怎样的顺序学习这些课程,才能无矛盾.顺利地完成学业--拓扑排序 拓扑序列是有向无环图中各顶点构成的有序序列.该序列满足如下条件:如果图中一顶点vi到另一顶点vj存在一条路径,那么vj在此图的拓扑排序序列中位于vi之后. 有向无环图(DAG)和 AOV网 有向无环图"(Directed Acyclic Graph,简称DAG AOV网 (Activity On Verte

算法系列笔记6(有关图的算法一—搜索,拓扑排序和强连通分支)

简单概念:对于图G(V,E),通常有两种存储的数据结构,一种是邻接矩阵,此时所需要的存储空间为O(V^2):第二种是邻接表,所需要的存储空间为O(V+E).邻接表表示法存在很强的适应性,但是也有潜在的不足,当要快速的确定图中边(u,v)是否存在,只能在顶点u的邻接表中搜索v,没有更快的方法,此时就可以使用邻接矩阵,但要以占用更多的存储空间作为代价:此外当图不是加权的,采用邻接矩阵存储还有一个优势:在存储邻接矩阵的每个元素时,可以只用一个二进位,而不必用一个字的空间. 图的搜索算法 搜索一个图示有

拓扑排序算法

#include<stdio.h>#include<stdlib.h>#define MAXVEX 100 //最大顶点数typedef char VertexType; //顶点typedef int EdgeType; //权值#define UNVISITED -1 //标记未访问#define VISITED 1 //标记未访问#define OK 1#define ERROR 0typedef int Status; typedef struct EdgeNode{ in

hiho一下 第四十八周 拓扑排序&#183;二【拓扑排序的应用 + 静态数组 + 拓扑排序算法的时间优化】

题目1 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论,当然小Hi和小Ho也参与到了其中.从大家各自了解的情况中,小Hi和小Ho整理得到了以下的信息: 校园网主干是由N个节点(编号1..N)组成,这些节点之间有一些单向的网路连接.若存在一条网路连接(u,v)链接了节点u和节点v,则节点u可以向节点v发送信息,但是节点v不能通过该链接向节点u发送信息. 在刚

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

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

拓扑排序(TopologicalSort)算法

拓扑排序算法应用: 有些事情做都需要按照流程的去做,比如你准备约你小女友去影院看速度与激情7大片,首先你想的是我怎么到达影院,然后达到影院,你可以先买票,或者等小女友来了一起买票,然后一起进电影大厅.....然后说说甜言蜜语时机成熟了有可以做下一步了:作为顶点:自己的位置,影院位置,小女友到达影院,买票,进大厅,作为顶点,比如都到达了影院买好票才可以一起进入,就是当一个顶点都被满足时才可以该顶点才可以做动作执行下一步.这是我自己的理解方式,你要还不理的话可能是我说的不够好! 1 /* 2 拓扑排

拓扑排序的算法

package ToPu; public class Graph { private final int MAX_VERTS = 20; private Vertex vertexList[]; private int adjMat[][]; private int nVerts; private char sortedArray[]; public Graph(){ vertexList = new Vertex[MAX_VERTS]; adjMat = new int [MAX_VERTS]