数据结构之图

  • 图的基本概念
  • 图的逻辑结构的应用
      • 顶点的度、入度、出度
      • 顶点与顶点的关系描述
      • 连通图、强连通图
      • 研究图的局部——子图
      • 连通分量
      • 强连通分量
      • 生成树
      • 生成森林
      • 边带权、带权图/网
  • 几种特殊的图
  • 图的存储结构
    • 邻接矩阵(基于顺序存储)
      • 邻接矩阵的实现
      • 如何求顶点的度,入度,出度
      • 邻接矩阵法存储带权图(网)
      • 邻接矩阵法存储带权图(网)实现
      • 邻接矩阵法的性能分析
      • 邻接矩阵的性质
    • 邻接表(顺序存储+链式存储)
      • 邻接表性能分析
      • 如何求顶点的度,入度,出度
    • 邻接表与邻接矩阵总结
    • 十字链表法(存储有向图)
    • 邻接多重表(存储无向图)
  • 基本操作
        • 判断是否存在边(x,y)或
        • 图G中与结点x邻接的边
        • 图G中插入顶点x
        • 图G中删除顶点x
        • 若图G中无(x,y)或,则向图G中添加该边
        • 求图G中顶点x的第一个邻接点,若有则返回顶点号。若无则返回-1.
        • 求图G中顶点x的第一个邻接点后的下一个邻接点,若有则返回顶点号。若无则返回-1.
  • 图的广度优先遍历(BFS)
    • 与树的广度优先遍历之间的联系
      • 树的广度优先遍历
      • 图的广度优先遍历
    • 算法实现
      • 广度优先遍历序列
      • 遍历序列的可变性
      • 算法存在的问题,最终版
    • 复杂度分析
    • 广度优先生成树
    • 广度优先生成森林
  • 图的深度优先遍历(DFS)
    • 与树的深度优先遍历之间的关系
      • 树的深度优先遍历
    • 算法实现
      • 算法要点
      • 图的深度优先遍历
      • 算法存在的问题——最终版
    • 复杂度分析
      • 深度优先遍历序列
    • 深度优先生成树
    • 深度优先生成森林
    • 图的遍历与图的连通性
  • 最小生成树
    • 最小生成树的概念
    • Prim算法(普里姆)
      • Prim算法(普里姆)实现的思想
    • Kryskak算法(克鲁斯卡尔)
      • Kryskak算法(克鲁斯卡尔)实现思想
    • 算法对比
  • 最短路径问题
    • 最短路径问题_BFS算法
      • BFS求无权图的单源最短路径
    • 最短路径问题_Dijkstra算法(迪杰斯特拉算法)
      • Dijkstra算法
    • 最短路径问题_Floyd算法(弗洛伊德算法)
      • Floyd算法
      • 代码实现
      • 复杂度
      • 算法总结
  • 有向无环图——描述表达式__DAG
      • DAG描述表达式
      • 解题思路
  • 拓扑排序__**AOV网**
      • 拓扑排序
      • 代码实现
      • 复杂度
      • 逆拓扑排序
      • 逆拓扑排序 的实现(DFS)
  • 关键路径_AOE
      • AOE网具有的性质:
      • 求关键路径的步骤
        • ①求所有事件的最早发生时间ve()
        • ②求所有事件的最迟发生时间vl()
        • ③求所有活动的最早发生时间e()
        • ④求所有活动的最迟发生时间I()
        • ⑤求所有或哦那个的时间余量d()
        • 求得关键活动、关键路径
      • 关键活动、关键路径的特性

图的基本概念

G Graph V Vertex E Edge
图是由顶点集V与边集E组成,记为G=(V,E),
V(G)表示图G中顶点的有限非空集;E(G)表示图G中顶点之间的关系(边)集合。
若V={v1,v2…vn},则用|V|表示图G中顶点的个数,即图G的阶。
若E={(u,v)|u∈U,v∈V},则用|E|表示图G中边的条数。
注意:
线性表可以是空表,树也可以是空树,但图不可以是空图,
即V(顶点集)一定是非空集,边集可以是空集

图的逻辑结构的应用

如铁路网络
微信(无向图)-》无向边(边)记为(v,w)或(w,v)
微博(有向图)-》有向边(弧)记为 v是弧尾[尾巴无箭头],w是弧头

顶点的度、入度、出度

对于无向图:顶点v的度是指依附于该顶点的边的条数,记为TD(v)。
对于有向图:
入度是以顶点v为终点的有向边的数目,记为ID(v)。
出度是以顶点v为起点的有向边的数目,记为OD(v)。
顶点v的度TD(v)=ID(v)+OD(v).

注意:
对于无向图:所有顶点的度之和 应该是等于这个无向图里面 边 的数量 乘于2
对于有向图:所有顶点的入度之和与出度之和是相等的且等于弧的这个条数。

顶点与顶点的关系描述

路径:顶点Vp到顶点Vq之间的一条路径,顶点序列,
回路:第一个顶点和最后一个顶点相同的路径,回路或环
简单路径:在路径序列中,顶点不重复出现的路径称为简单路径。
简单回路:除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路称为简单回路。
路径长度:路径上 边 的数目
点到点的距离:从顶点u出发到顶点v的最短路径若存在,则此路径的长度称为从u到v的距离。若从u到v根本不存在路径,则记该距离为无穷

连通图、强连通图

无向图中,若从顶点v到顶点w有路径存在,则称v和w是连通
有向图中,若从顶点v到顶点w从顶点w到顶点v之间都有路径,则称这两个顶点是强连通

无向图,若图G中任意两个顶点都是连通的,则称图G为连通图,否则称为非连通图
有向图,若图中任何一对顶点都是强连通的,则称此图为强连通图

注意:
对于n个顶点的无向图G,
若G是连通图,则最少有n-1条边
若G是非连通图,则最多有(Cn-1^2)条边
注意:
对于n个顶点的有向图G,
若G是强连通图,则最少有n条边。(形成回路)

研究图的局部——子图

数据结构之图_第1张图片
设有两个图G=(V,E)和G’=(V’,E’)
若V’是V的子集,且E’是E的子集,则G’是G的子图。
数据结构之图_第2张图片
若有满足V(G’)=V(G)的子图G’,则称其为G的生成子图
有向图 同理可得

连通分量

无向图的极大连通子图称为连通分量(子图必须连通,且包含尽可能多的顶点和边)
数据结构之图_第3张图片
每一个连通分量都是原图的一个子图,并且都是连通的
eg 将中国铁路客运线路图 分为 大陆铁路网 海南岛铁路网 台湾岛铁路网三个连通分量

强连通分量

有向图的极大连通子图称为强连通分量
数据结构之图_第4张图片

生成树

(无向图)
连通图生成树是包含图中全部顶点的一个极小连通子图
(边尽可能少)
数据结构之图_第5张图片
该生成树中 若顶点为n,则边为n-1
若顶点为n,边为n,则构成回路
若顶i点为n,边为n-,则构成非连通图

生成树保证顶点都是连通的

生成森林

非连通图中,连通分量的生成树构成了非连通图生成森林
数据结构之图_第6张图片

边带权、带权图/网

数据结构之图_第7张图片

边的权-:在一个图中,每一条边都可以标上具有某种含义的数值,该数值称为该边的权值
带权图/网:边上带有权值的图称为带权图
带权路径长度:当图是带权图时,一条路径上所有边的权值之和,称为该路径的带权路径长度·

倘若是有向图,即可给各边赋予一个数值 eg:转发概率
image.png

几种特殊的图

数据结构之图_第8张图片
**无向完全图 ** :无向图中任意两个顶点都存在边
数据结构之图_第9张图片
有向完全图:有向图中任意两个顶点之间都存在方向相反的弧
数据结构之图_第10张图片
稀疏图:边很少的图
反之,
稠密图

数据结构之图_第11张图片

:不存在贿赂,且连通的无向图
数据结构之图_第12张图片
有向树:一个顶点的入度为0,其余顶点的入度均为1的有向图,称有向树

图的存储结构

邻接矩阵(基于顺序存储)

注意;相同的图 邻接矩阵的表示方式唯一
数组实现的顺序存储,空间复杂度高,不适合存储稀疏图
数据结构之图_第13张图片
1表示两顶点连接,0表示两顶点不连接
有向图中 a行b列 由a指向b的弧

邻接矩阵的实现

定义一个二维数组
数据结构之图_第14张图片
eg:edge[a][b]=0;//从a顶点到b顶点存在 边

如何求顶点的度,入度,出度

无向图:第i个节点的度=第i行(或第i列)的非0元素的个数 O(n)
有向图:
第i个节点的出度=第i行的非0元素的个数 O(n)
第i个节点的入度=第i列的非0元素的个数 O(n)
第i个节点的度=第i个节点的出度+第i个节点的入度

邻接矩阵法存储带权图(网)

数据结构之图_第15张图片

邻接矩阵法存储带权图(网)实现

数据结构之图_第16张图片
无穷或者0代表 没有这条边 使用宏定义常量来表示无穷

邻接矩阵法的性能分析

倘若该图 有n个顶点 则需要O(n)级别的空间复杂度来存储该图的顶点
存储边需要n*n个空间, 则需要O(n^2)级别的空间复杂度来存储该图的边
即:
邻接矩阵的空间复杂度与顶点有关(无论边数是否存在都存储)–适合存储稠密图

注意:由于无向图的邻接矩阵是对称矩阵,可以压缩存储(只存上三角或下三角)
图为压缩矩阵
数据结构之图_第17张图片

邻接矩阵的性质

数据结构之图_第18张图片
a11a14:a的1行1列a的1行4列=00
:向量AA
向量AD=向量AD=0即不存在
a12a24:a的1行2列a的2行4列=11
:向量AB
向量BD=向量AD=1存在

看右下角图:从B到B长度为2的路径有3条
数据结构之图_第19张图片
看右下角图:从B到B长度为3的路径有2条

邻接表(顺序存储+链式存储)

注意;相同的图 邻接表的表示方式并不唯一
数据结构之图_第20张图片
数据结构之图_第21张图片
数据结构之图_第22张图片

对比:树的孩子表示法
数据结构之图_第23张图片

邻接表性能分析

数据结构之图_第24张图片
无向图:data存储顶点信息,*first存储边信息 边结点信息会存两份,如(a,b)会存(a,b)和(b,a)_虽然两者是同一条边 _ , 所以整体空间复杂度为O(|V|+2|E|)

有向图:整体空间复杂度为O(|V|+|E|)

如何求顶点的度,入度,出度

无向图:遍历 data顶点对应的first 即可得出度
有向图:遍历data顶点对应的
first 即可得出 出度,依次遍历所有的data顶点的对应的*first 找出指向所有求data的数量 即可得出 入度 度=出度+入度
(时间复杂度较高)

邻接表与邻接矩阵总结

数据结构之图_第25张图片
数据结构之图_第26张图片

十字链表法(存储有向图)

过于复杂 暂不学习

邻接多重表(存储无向图)

过于复杂 暂不学习

基本操作

数据结构之图_第27张图片

判断是否存在边(x,y)或

数据结构之图_第28张图片
无向图——邻接矩阵:找到x行y列对应的元素是否为1 O(1)
无向图——邻接表:O(1)~O(|V|)
有向图——邻接矩阵O(1)
有向图——邻接表:O(1)~O(|V|)

图G中与结点x邻接的边

无向图——邻接矩阵:遍历x行x列所有的对应的元素是否为1 O(|V|)
无向图——邻接表:遍历x边结点相连的链表 O(1)~O(|V|)
有向图——邻接矩阵 O(|V|)
有向图——邻接表:出边O(1)~O(|V|) 入边O(|E|)

图G中插入顶点x

无向图——邻接矩阵:添加x行x列元素值都设为0 O(1)
无向图——邻接表:表末尾插入data 指针为null O(1)~O(|V|)
有向图——邻接矩阵 添加x行x列元素值都设为0 O(1)
有向图——邻接表:表末尾插入data 指针为null O(1)~O(|V|)

图G中删除顶点x

无向图——邻接矩阵:将x行x列元素值都设为0,添加标记将x标记为null O(|V|)
无向图——邻接表:删除边x,与边相邻的指针之外,还得找其他所有的边中是否有与相连的指针 O(1)~O(|E|)
有向图——邻接矩阵 添加x行x列元素值都设为0 O(|V|)
有向图——邻接表:删除边x,与边相邻的指针 删除出边 O(1)~O(|V|) 删除入边(|E|)

若图G中无(x,y)或,则向图G中添加该边

无向图——邻接矩阵:添加x行x列元素值都设为1 O(1)
无向图——邻接表:找到指定data, 指针为后增加指针 O(1)~O(|V|)
有向图——邻接矩阵:添加x行x列元素值都设为1 O(1)
有向图——邻接表:找到指定data, 指针为后增加指针 O(1)~O(|V|)

求图G中顶点x的第一个邻接点,若有则返回顶点号。若无则返回-1.

无向图——邻接矩阵:找x行元素值第一个为1,则返回列号 O(1)~O(|V|)
无向图——邻接表:找到边结点第一个结点后第一个指针 O(1)
有向图——邻接矩阵:找x行元素值第一个为1,则返回列号 出行 O(1)~O(|V|)
有向图——邻接表:找到边结点第一个结点后第一个指针 出边 O(1)遍历所有边结点,第一个结点后第一个指针 ~O(|V|)

求图G中顶点x的第一个邻接点后的下一个邻接点,若有则返回顶点号。若无则返回-1.

获取图G中边(x,y)或对应的权值
设置图G中边(x,y)或对应的权值为v

判断某一条边是否存在相同
方法类似

图的广度优先遍历(BFS)

树本身就是一种特殊的图 树的广度优先遍历(层序遍历)

与树的广度优先遍历之间的联系

树的广度优先遍历

数据结构之图_第29张图片
树的广度优先遍历:从根结点出发,找到和根结点相邻的所有节点,接下来从234出发找到与其相邻的所有结点……【横向的找】

树的辅助队列
数据结构之图_第30张图片

图的广度优先遍历

数据结构之图_第31张图片
图的广度优先遍历:例如从2结点出发,找到和2结点相邻的所有节点,接下来从1 6出发找到与其相邻的所有结点……【横向的找】

通过某个结点找到与之相邻的其他结点
由于图会产生回路(树不可能产生回路)因此,需要给节点添加标记

算法实现

数据结构之图_第32张图片

1.找到与一个顶点相邻的所有顶点————使用FirstNeighbor(G,x):找到顶点的邻接点,NextNeighbor(G,x,y),找到除y之外的顶点x的下一个邻接点的顶点
2.定义bool visited[MAX_VERTEX_NUM]; 标记是否访问过
数据结构之图_第33张图片

广度优先遍历序列

数据结构之图_第34张图片

遍历序列的可变性

请注意:
使用邻居接表存储,广度优先遍历序列的结果可能会不同
使用邻接矩阵存储,广度优先遍历序列的结果唯一

算法存在的问题,最终版

倘若图为非连通图
最终版
数据结构之图_第35张图片

复杂度分析

对于最终版,空间复杂度主要来自于辅助队列
最坏情况下O(|V|)

邻接矩阵存储的图:时间复杂度为 O(|V^2|)
邻接表存储的图:时间复杂度为 O(|V|+|E|)

广度优先生成树

数据结构之图_第36张图片
红色的线为n-1条 共有n个顶点
若只有红线,则变成广度优先生成树

广度优先生成森林

数据结构之图_第37张图片

图的深度优先遍历(DFS)

与树的深度优先遍历之间的关系

树的深度优先遍历

树的深度优先遍历 分为先根遍历后根遍历
图的深度优先遍历类似于树的先根遍历

数据结构之图_第38张图片
数据结构之图_第39张图片

算法实现

算法要点

数据结构之图_第40张图片

图的深度优先遍历

数据结构之图_第41张图片
先访问一个节点,然后再用一个循环来依次检查和这个节点相邻的其他节点,然后再进行更深一层的访问

算法存在的问题——最终版

非连通图,则无法遍历完所有结点
最终代码
数据结构之图_第42张图片

复杂度分析

空间复杂度:来自函数调用栈,最坏情况,递归深度为O(|V|)
时间复杂度=访问各个结点所需要时间+探索各边所需要时间
邻接矩阵存储的图:
查找每个顶点的邻接点都需要O(|V|)的时间,而总共有|V|个顶点
时间复杂度=O(|V|²)
邻接表存储的图:
访问|V|个顶点需要|V|个时间
查找每个顶点的邻接点都需要O(|E|)的时间
时间复杂度=O(|E|+|V|)

深度优先遍历序列

数据结构之图_第43张图片
数据结构之图_第44张图片

同一个图的邻接矩阵表示方式唯一,因此深度优先遍历序列唯一
同一个图的邻接表表示方式不唯一,因此深度优先遍历序列不唯一

深度优先生成树

数据结构之图_第45张图片
只保留红边的话,就构成了一个树

深度优先生成森林

若一个图是非连通的 需要多次调用DFS函数(深度优先遍历)
每调用一次DFS,则可生成一个深度优先生成树
多个树,就构成森林

图的遍历与图的连通性

对无向图进行BFS/DFS遍历
调用BFS/DFS函数的次数=连通分量数=生成树的数量

对于连通图,则只需要调用一次BFS/DFS

对有向图进行BFS/DFS遍历
调用BFS/DFS函数的次数具体问题具体分析

对于连通图,若起始顶点到其他各顶点都有路径,则只需要调用1次BFS/DFS
若有向图是强连通图,则从任一顶点出发都只需要调用1次BFS/DFS

最小生成树

最小生成树的概念

连通图的生成树:包含图中全部顶点的一个极小连通子图。

带权连通图可能有多个生成树,从其所有的生成树当中,找到各边权值之和最小的生成树。
image.png
最小生成树可能有多个,但边的权值之和总是唯一且最小的
最小生成树的边数=顶点数-1.————去掉一个边构不成连通,增加一条边出现回路
注意:
如果一个连通图本身就是一颗树,则其最小生成树就是其本身
只有连通图才有生成树,非连通图只有生成森林

Prim算法(普里姆)

从某一个顶点开始构建生成树;每次把代价最小新顶点纳入生成树,直到所有顶点都纳入为止。

Prim算法(普里姆)实现的思想

数据结构之图_第46张图片

第一轮处理,循环遍历所有结点,找到lowCast最低的,且没有加入树顶点(lowCost距离树的各个顶点的最短距离)
第二轮处理,循环遍历所有结点,找到lowCast最低的,且没有加入树顶点(
再次循环遍历,更新还没有加入各个顶点的lowCast值)
……
总时间复杂度为O(n²),即O(|V|²)

Kryskak算法(克鲁斯卡尔)

每次选择一条权值最小的边,使这条边的两头连通(原本连通的不选),直到所有结点都连通

Kryskak算法(克鲁斯卡尔)实现思想

数据结构之图_第47张图片
第一轮:检查第一条边的两个顶点是否连通(是否属于同一集合)**【并查集】,不连通,连通起来
第二轮:检查第二条边的两个顶点是否连通(是否属于同一集合)
{vo,v3}是一个集合,**不连通,连通起来
……
总时间复杂度为O(elog2 e)

算法对比

数据结构之图_第48张图片

最短路径问题

image.png
image.png
单独一个源头,从该源头出发,到达其他任意一个顶点可以走的最短路径-单源最短路径

最短路径问题_BFS算法

BFS求无权图的单源最短路径

无权图可以视为每条边权值为1的是带权图
数据结构之图_第49张图片
若以2号为根则
数据结构之图_第50张图片
数据结构之图_第51张图片

最短路径问题_Dijkstra算法(迪杰斯特拉算法)

单独一个源头,从该源头出发,到达其他任意一个顶点可以走的最短路径-单源最短路径
BFS算法的局限性 :无法适用于带权图
带权路径长度:当图是带权图时,一条路径上所有边的权值之和,称之为该路径的带权路径长度,简称路径长度

Dijkstra算法

数据结构之图_第52张图片
eg:求vo点到其他各个顶带点的最短路径:
先初始化3个数组,
标记各个顶点是否已经找到最短路径的数组final【5】:表示到目前为止是否找到从v0到这些顶点的最短路径
最短路径长度的数组dist【5】:目前为止能够找到的最短的最优的一条路径的长度
路径上的前驱的数组path【5】:用于记录每一个顶点在最短路径上的直接前驱
三个数组与顶点一一对应
第一轮:循环遍历所有结点,找到还没确定的最短路径,且dist最小的Vi(V4),令final[i]=true
检查所有与vi(v4)相连的顶点,更新dist【5】与path【5】中的数据;
数据结构之图_第53张图片
第二轮:循环遍历所有结点,找到还没确定的最短路径,且dist最小的Vi(V3),令final[i]=true
检查所有与vi(v3)相连的顶点,更新dist【5】与path【5】中的数据;
数据结构之图_第54张图片
……
最终
数据结构之图_第55张图片
V0到V2的最短带权路径长度为dist[2]=9
通过path【】可知,V0到V2的最短带权路径:v2—v1–v4–v0
数据结构之图_第56张图片

注意:distance的dist【】和prim的lowcost【】两个数组的作用类似

注意:如果存在负权值的边,distance算法就会**失效,**找不到最短的带权路径

最短路径问题_Floyd算法(弗洛伊德算法)

各个顶点的之间的最短路径(动态规划)、

Floyd算法

数据结构之图_第57张图片
初始:不允许中转
两个初始的矩阵(二维数组),第一个矩阵为该图的邻接矩阵,为就目前来看,各个顶点的最短路径长度 第二个矩阵为目前能找到的最短路径当中两个顶点之间的一个中转点:(刚开始,所有的顶点之间都不可以有中转点,所以会将所有的这些path值设置为-1 )
#v0:若允许在v0中转
由初始阶段的两个矩阵的信息求该阶段的信息 (遍历上一阶段留下来的这个矩阵A ,对于矩阵A中每一个具体的元素,我们都需要进行一次检查)
数据结构之图_第58张图片
#1:若允许在v0,v1中转
数据结构之图_第59张图片
数据结构之图_第60张图片
……
数据结构之图_第61张图片

代码实现

数据结构之图_第62张图片

复杂度

时间复杂度:O(|V|²)
空间复杂度:O(|V|²)
弗洛伊德算法可以解决带负权值图的问题,但解决不了带有负权回路的图

算法总结

数据结构之图_第63张图片

有向无环图——描述表达式__DAG

有向无环图(DAG)
若一个有向图中不存在环路,则称为有向无环图
数据结构之图_第64张图片

DAG描述表达式

eg:
数据结构之图_第65张图片
转变为有向无环图
数据结构之图_第66张图片

解题思路

数据结构之图_第67张图片

数据结构之图_第68张图片
数据结构之图_第69张图片

数据结构之图_第70张图片

数据结构之图_第71张图片

拓扑排序__AOV网

有向无环图(DAG)
若一个有向图中不存在环路,则称为有向无环图
DAG图的第二个应用——拓扑排序
AOV网(用顶点表示活动结构的网):
用DAG网(有向无环图)表示一个工程。顶点表示活动,有向图表示活动Vi先于活动Vj进行
image.png

拓扑排序:在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序:
①每一个顶点出现且只出现一次。
②若顶点A在序列中排在顶点B的前面,则在图中不存在从顶点B到顶点A的路径。
或定义为:拓扑排序是对有向无环图的顶点的一种排序,它使得若存在一条从顶点A到顶点B的路径,则在排序中顶点B出现在顶点A的后面。每一个AOV网都有一个多个拓扑排序序列
(拓扑排序:找到做事的先后顺序)

拓扑排序

拓扑排序的实现:
①从AOV网中选择一个没有前驱(入度为0)的顶点并输出。
②从网中删除该顶点和所有以它为起点的有向边。
③重复①和②直到当前的AOV网为空当前网中不存在无前驱的顶点为止。
image.png
注意:若原图存在回路,则无法进行拓扑排序

代码实现

数据结构之图_第72张图片

复杂度

时间复杂度:O(|V|+|E|)
若采用邻接矩阵,则需要O(|V|²)

逆拓扑排序

数据结构之图_第73张图片
对于一个AOV网,如果采用下列步骤进行排序,则称之为逆拓扑排序:
①从AOV网中选择一个没有后继(出度为0)的顶点并输出。
②从网中删除该顶点和所有以它为终点的有向边。
③重复①和②直到当前的AOV网为空
数据结构之图_第74张图片
逆邻接表(指向顶点的)

逆拓扑排序 的实现(DFS)

数据结构之图_第75张图片

关键路径_AOE

AOE网:在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动所需时间),称之为用边表示活动的网络,简称AOE网
数据结构之图_第76张图片

AOE网具有的性质:

①只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始。
②只有在进入某顶点的各有向边所代表的活动都已经结束时,该顶点所代表的事件才能发生。
另外,有些活动是可以并行进行的

在AOE网中仅有一个入度为0的顶点,称之为开始顶点(源点),它表示整个工程的开始;
也仅有一个入度为0的顶点,称之为结束顶点(汇点),它表示整个工程的结束。

从源点到汇点的有向路径可能有多条,所有路径中,具有最大路径长度的路径称之为关键路径,而把关键路径上的活动称之为关键活动

完成整个工程的最短时间就是关键路径的长度,若关键活动不能按时完成,则整个工程的完成时间就会延长
数据结构之图_第77张图片
事件Vk的最迟发生时间——它是在不推迟整个工程完成的前提下,该事件最迟必须发生的时间。
活动的最迟开始时间——它是指该活动弧的终点所表示事件的最迟发生时间于该活动所需时间之差

求关键路径的步骤

数据结构之图_第78张图片
时间余量的d(x)为0的活动为关键活动 =

①求所有事件的最早发生时间ve()

数据结构之图_第79张图片
拓扑排序 v1、v3、v2、v5、v4、v6
数据结构之图_第80张图片

②求所有事件的最迟发生时间vl()

数据结构之图_第81张图片
逆拓扑排序v6、 v1、v5、v4、、v2、v3、v1
数据结构之图_第82张图片

③求所有活动的最早发生时间e()

数据结构之图_第83张图片
数据结构之图_第84张图片

④求所有活动的最迟发生时间I()

若边表示活动ai,则有l(i)=vl(j)-Weight(vk,vj)
image.png

数据结构之图_第85张图片

⑤求所有或哦那个的时间余量d()

image.png
数据结构之图_第86张图片

求得关键活动、关键路径

关键活动:a2、a5、a7
关键路径:V1》V3》V4》V6

关键活动、关键路径的特性

若关键活动耗时增加,则整个工程的工期将增长
缩短关键活动的时间,可以缩短整个工程的工期
当缩短到一定程度时,关键活动可能会变成非关键活动

可能存在多条关键路径,只提高一条关键路径上的关键活动速度并不能缩短整个工程的工期,只有加快那些包括在所有关键路径上的关键活动才能达到缩短工期的目的

你可能感兴趣的:(数据结构,算法,数据结构,图论,算法)