拓扑排序

数据结构(三十五)拓扑排序

孤街醉人 提交于 2020-01-16 14:04:46
  一、拓扑排序的定义   1.AOV网:在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,称为AOV网(Activity On Vertex Network)。   2.拓扑序列:设G={V,E}是一个具有n个顶点的有向图,V中的顶点序列v1,v2,...,vn,满足若从顶点vi到vj有一条路径,则在顶点序列中顶点vi必在vj之前,这样的顶点序列为一个拓扑序列。   3.拓扑排序:拓扑排序是对一个有向图构造拓扑序列的过程。构造时会有两个结果,如果此网的全部顶点都被输出,则说明它是不存在环(回路)的AOV网;如果输出的顶点少了,说明这个网存在环(回路),不是AOV网。   例如,      这样的AOV拓扑序列不止一条。序列v0v1v2v3v4v5v6v7v8v9v10v11v12v13v14v15v16是一个拓扑序列,序列v0v1v4v3v2v7v6v5v8v10v9v12v11v14v13v15v16。   二、拓扑排序算法   1.拓扑排序算法的基本思路:   从AOV网中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止。   2.由于拓扑排序的过程中,需要删除顶点,显然用邻接表更加方便,因此需要创建一个邻接表

拓扑排序算法

给你一囗甜甜゛ 提交于 2020-01-16 14:01:10
#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 0 typedef int Status; typedef struct EdgeNode { int adjvex; //该顶点对应的下标 EdgeType weight; //权重 struct EdgeNode * next; }EdgeNode; typedef struct //顶点结构 { int in; //记录入度 VertexType data; EdgeNode * firstedge; }VertexNode,AdjList[MAXVEX]; typedef struct { AdjList adjList; int numVertexes; int numEdges; int Mark[MAXVEX]; //标记是否被访问过 }GraphAdjList; //图结构 //初始化邻接表 void InitGraphAdjList(GraphAdjList * G

【算法总结】图论-拓扑排序

∥☆過路亽.° 提交于 2020-01-16 13:29:55
【算法总结】图论-拓扑排序 一、概念 设有一个有向无环图(DAG 图),对其进行拓扑排序即求其中结点的一个拓扑序列,对于所有的有向边(U,V)(由U指向V),在该序列中结点U都排列在结点 V 之前。满足该要求的结点序列,被称为 满足拓扑次序的序列 。求这个序列的过程,被称为 拓扑排序 。 由满足拓扑次序序列的特征我们也能得出其如下特点:若结点U经过若干条有向边后能够到达结点V,则在求得的序列中U必排在V之前。 在了解了拓扑次序的定义以后,我们就知道了前文中为什么将拓扑排序限定在一个有向无环图上。若图无向,则边的两个顶点等价,不存在先后关系;若图为有向图,但存在一个环路,则该环中所有结点无法判定先后关系(任意结点间都能通过若干条有向边到达)。 二、拓扑排序的方法 首先,所有有入度(即以该结点为弧头的弧的个数)的结点均不可能排在第一个。那么,我们选择一个 入度为0的结点 ,作为序列的 第一个结点 。当该结点被选为序列的第一个顶点后,我们将该点从图中删去,同时删去以该结点为弧尾的所有边,得到一个新图。那么这个新图的拓扑序列即为原图的拓扑序列中除去第一个结点后剩余的序列。 同样的,我们 在新图上选择一个入度为0的结点 ,将其作为原图的第二个结点,并在新图中删去该点以及以该点为弧尾的边。这样我们又得到了一张新图,重复同样的方法,直到所有的结点和边都从原图中删去。

拓扑排序(topological sort)

﹥>﹥吖頭↗ 提交于 2020-01-16 13:29:33
一、定义: 对一个 有向无环图 (Directed Acyclic Graph简称DAG) G进行拓扑排序 是将G中所有顶点排成一个线性序列 使得图中任意一对顶点u和v 若边(u,v)∈E(G) 则u在线性序列中出现在v之前 注意: 有时候,这里的排序不是唯一的 二、算法 O(V+E) 有两种:入度表、dfs (一)、入度表 O(V+E): 找出图中0入度的点 依次在图中删除这些点 于是再找删掉点之后的0入度的点 然后再删除...再找点 入度为0的点 用 队列 图 用 邻接表 #include<cstdio> #include<algorithm> #include<queue> using namespace std; const int maxn = 10005; int n,m,cnt;//cnt存储ans数组的下标 bool a[maxn][maxn];//邻接矩阵 int edge[maxn],ans[maxn];//edge[i]第i个点的入度,ans答案队列 queue<int> q; void topo_sort() { for(int i = 1;i <= n;i++) if(!edge[i]) q.push(i);//将所有入度为0的点加入队列中 while(!q.empty()) { const int u = q.front(); ans[++cnt] =

有环无向图应用--拓扑排序

孤者浪人 提交于 2020-01-16 13:27:10
转自大神:思路超清晰: https://blog.csdn.net/qq_37618797/article/details/81070577 前言看大神的吧 复制没图片 代码: 1 #include <iostream> 2 3 using namespace std; 4 #define N 13 5 int main() 6 { 7 int map[N][N]; //邻接矩阵 8 // 初始化矩阵的值全部为0表示各个顶点间没有边连接 9 for(int i = 0; i <= N-1; i++){ 10 for(int j = 0; j <= N-1; j++){ 11 map[i][j] = 0; 12 } 13 } 14 15 int a,b; //定义两个变量,用来输入 16 int v,l; //顶点数和边数 17 18 cout << "请输入顶点数:"; 19 cin >> v; 20 cout << "请输入边数:"; 21 cin >> l; 22 cout << "请输入边:" << endl; 23 24 for(int i = 1; i <= l; i++){ 25 cin >> a >> b; 26 map[a][b] = 1; // 表示顶点a指向顶点b的边 27 } 28 cout << "邻接矩阵如下所示\n" << endl; 29 for

图论————拓扑排序

ε祈祈猫儿з 提交于 2020-01-16 13:25:42
拓扑排序是一个非常重要的知识点,不只是在图论上会应用到,在其他地方也会涉及。 一.定义 对一个有向无环图(Directed Acyclic Graph, DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。 通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。(百度上抄的,不懂也没事),总之拓扑排序就是一种遍历方式。 二.拓扑序列算法思想 (1)从有向图中选取一个没有前驱(即入度为0)的顶点,并输出之; (2)从有向图中删去此顶点以及所有以它为尾的弧; 重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。 代码实现 原题链接: https://www.acwing.com/problem/content/850/ #include<bits/stdc++.h> using namespace std; const int N = 100010, M = 100010; struct EDGE { int to,next; } edge[M]; int d[N]; int n,m; int h[N],cnt; int dis[N]; void add(int u, int v) { edge[++cnt].to=v; edge[cnt]

20182318 2019-2020-1 《数据结构与面向对象程序设计》实验九报告

醉酒当歌 提交于 2020-01-12 13:48:01
20182318 2019-2020-1 《数据结构与面向对象程序设计》实验九报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 王振澳 学号:20182318 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分) PS:本题12分。目前没有明确指明图的顶点和连通边,如果雷同或抄袭,本次实验0分。、 2. 实验过程及结果 生成树 图的遍历 拓扑排序 prim算法 迪杰斯特拉算法 具体代码见码云 3. 实验过程中遇到的问题和解决过程 问题一:实验过程中对图各个边的权值进行赋值的操作问题 问题一解决办法:选择使用二维数组,并将0行和0列设置为0,不使用。便于后面程序编写时的理解,给自己减少负担。这个二维数组需要自己手动写好在代码里。 其他(感悟、思考等) 实验终于做完了,有很多遗憾

拓扑排序

久未见 提交于 2020-01-12 09:34:31
定义 在一个有向图中找一个拓扑序列的过程称为拓扑排序 拓扑排序: 设 G=(V,E)是一个具有n个顶点的有向图,V中的顶点序列v1,v2,…,vn,称为一个拓扑序列。 方法 拓扑排序方法如下: 从有序图中选择一个没有前驱(即入度为0)的顶点并且输出它。 从图中删去该顶点,并且删去从该顶点发出的全部有向边。 重复上述两步,直到剩余的图中不再存在没有前驱的结点为止。 这样操作的结果有两种:一种是图中全部顶点都被输出,即该图中所有顶点都在去拓扑序列中,这说明图中不存在回路;另一种就是图中顶点未被全部输出,这说明图中存在回路。所以可以通过对一个有向图进行拓扑排序,看是否产生全部顶点的拓扑序列来确定该图中是否存在回路问题。 对于给定的有向图,可以采用邻接表作为存储结构,邻接表定义中的VNode类型修改如下: typedef struct { Vertex data; //顶点信息 int count; //增加数据域:存放顶点入度 ArcNode * firstarc; //指向第一个邻接点 }VNode; //头结点类型 对应的拓扑排序算法如下: void TopSort(AdjGraph *G) //拓扑排序算法 { int i,j; int St[MAXV].top=-1; //栈St的指针为top ArcNode *p; for(i=0;i<G->n;i++) //入度置初值0 G-

拓扑排序

孤街醉人 提交于 2020-01-11 13:09:13
简单的回顾了一下拓扑排序,并做了几道题,在此做一下总结。 拓扑排序算法原理比较简单,但在实现上,给我提供了一种比较好用的技巧。 对这种需要判断环的存在的,需要区分历史遍历过的和现在正在遍历的。这里对 v i s [ ] vis[] v i s [ ] 进行了扩展,用 − 1 -1 − 1 来表示标记现在正在访问的路径,而访问结束标记为 1 1 1 。当然,这个只能在 d f s dfs d f s 中使用。 bool dfs ( int node ) { vis [ node ] = - 1 ; For ( i , 0 , G [ node ] . size ( ) - 1 ) { int u = G [ node ] [ i ] ; if ( vis [ u ] == - 1 ) return 0 ; if ( vis [ u ] == 1 ) continue ; -- deg [ u ] ; if ( ! deg [ u ] ) if ( dfs ( u ) == 0 ) return 0 ; } vis [ node ] = 1 ; return 1 ; } 当然,用堆或者队列之类的也是可以进行维护的。不过对于判断是否有环的话,还是 d f s dfs d f s 更适合。 下面来说一说具体的题目: H i h o c o d e r 1174 Hihocoder1174

拓扑排序

大憨熊 提交于 2020-01-10 17:44:52
拓扑排序 一个较大的工程往往被划分成许多子工程,我们把这些子工程称作活动(activity)。在整个工程中,有些子工程(活动) 必须在其它有关子工程完成之后才能开始 ,也就是说,一个子工程的开始是以它的所有前序子工程的 结束为先决条件 的,但有些子工程没有先决条件,可以安排在任何时间开始。为了形象地反映出整个工程中各个子工程(活动)之间的先后关系,可用一个有向图来表示,图中的顶点代表活动(子工程),图中的有向边代表活动的 先后关系 ,即有向边的起点的活动是终点活动的前序活动, 只有当起点活动完成之后,其终点活动才能进行 。通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。 每次去取出入读度为0的点,这些点的序列就是拓扑排序 如在学习一门课程之前必须要学习另一门课程,才可以学习这门课,好比学习高数之前要有高中数学的基础。 拓扑排序模板题 POJ2367 Sample Input 5 0 4 5 1 0 1 0 5 3 0 3 0 Sample Output 2 4 5 3 1 题目大意: 输入一个是N = 5代表有五条边,接下来第 i 行输入的数字代表 i 这个点指向的点,以0结束 Sample Input 5 0 1 这个点没有连通的点。 4 5 1 0 2 - > 4 , 2 - > 5