[记录本章包含哪些内容]
未攻克
[记录还不会的知识点]
笔记
大纲要求
-
图的基本概念
-
图的存储及基本操作:邻接矩阵、邻接表、邻接多重表、十字链表
-
图的遍历:深度优先搜索、广度优先搜索
-
图的基本应用:最小(代价)生成树、最短路径、拓扑排序、关键路径
-
主要掌握
- 深度优先搜索与广度优先搜索
- 图的基本概念及基本性质、图的存储结构(邻接矩阵、邻接表、邻接多重表和十字链表)及其特性、存储结构之间的转化、基于存储结构上的各种遍历操作和各种应用(拓扑排序、最小生成树、最短路径和关键路径)等
- 图相关算法只需掌握基本思想和实现步骤,实现代码为非重点
图的概念
基本定义及常见术语
- 图的顶点集 V ( G ) V(G) V(G) 一定优先非空
常见术语
- [!] 生成树、生成森林
1.连通图的生成树是包含图中全部顶点的一个极小连通子图。
2.若图中顶点数为 n,则它的生成树包含 n-1 条边。
3. 包含图中全部顶点的极小连通子图,只有生成树满足这个极小条件,对生成树而言,若砍去它的一条边,则会变成非连通图,若加上一条边则会形成一个回路。
4. 在非连通图中,连通分量的生成树构成了非连通图的生成森林
5. ==非连通情况下边最多的情况:==由 n-1 个顶点构成一个完全图,此时再加入一个顶点则变成非连通图
6. ==有向图强连通情况下边最少的情况:==至少需要 n 条边,构成一个环路
【注🧨】区分极大连通子图和极小连通子图。极大连通子图要求子图必须连通,而且包含尽可能多的顶点和边;极小连通子图是既要保持子图连通又要使得边数最少的子图
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
答案 | A | C | D | C | A | A | B | A | ||||||
序号 | 15 | 16 | 17 | 18 | 19 | |||||||||
答案 | D | A | D |
- C
有向完全图一定是强连通有向图
- 强连通时,需要构成一个环路,选 A
- 有向图,有出有回
- 出的时候有 n-1
- 回的时候有 n-1
- 出+回 = 2 n-2
- C
- I 连通分量是一个极大连通子图
- II 生成树是一个无环子图
12. C
- 要想连通分量最多,让整个图比较分散
- 有 21 条边,最多可以照顾到 n ( n − 1 ) / 2 = 21 n(n-1)/2 = 21 n(n−1)/2=21, n = 7 n=7 n=7
- 剩余顶点数=51-7=44
- 这 44 个顶点可以分别构成一个连通分量+由 7 个顶点构成的连通分量=45
- B
- 强连通分量:两个点之间有来有往
- B 本身是一个
- 可以看顶点是否既有出又有进
- B 若具有 n 个顶点的图是一个环,则它有 n 棵生成树
- C
- 森林是由树组合而成的
- 假设该森林中有 X 棵树
- 对每一棵树,都有顶点比边多 1,则 X 棵树=n 个顶点-e 条边 = n-e
- A
- 无向连通图的所有顶点的度之和为偶数,因为既有出又有入
- B
- 要求顶点个数最少,顶点度越大,顶点个数越少
图存储及基本操作
图的存储必须完整、准确的反映顶点集和边集的信息。根据不同图的结构和算法,采用不同的存储方式将对程序的效果产生相当大的影响。因此所选的存储结构应适合于待求解的问题。
图的存储
-
邻接表易找出度
-
[!] 邻接表中顶点的出度、入度和度:
- 出度 O D ( v i ) = 单链出边表中链接的结点数 OD (v_i)=单链出边表中链接的结点数 OD(vi)=单链出边表中链接的结点数
- 入度 I D ( v i ) = 邻接点域为 v i 的弧个数 ID(v_i)=邻接点域为v_i的弧个数 ID(vi)=邻接点域为vi的弧个数
- 度 T D ( v i ) = O D ( v i ) + I D ( v i ) TD(v_i)=OD(v_i)+ID(v_i) TD(vi)=OD(vi)+ID(vi)
-
[!] 邻接表和邻接矩阵的区别与联系
1.联系
邻接表中每个链表对应于邻接矩阵中的一行,链表中结点个数等于一行中非零元素的个数
2.区别
①对于任一确定的无向图,邻接矩阵是唯一的(行列号与顶点编号一致),但邻接表不唯一(链接次序与顶点编号无关)
②邻接矩阵的空间复杂度为 O ( n 2 ) O(n^2) O(n2),而邻接表的空间复杂度为 O ( n + e ) O(n+e) O(n+e)
3.用途
邻接矩阵多用于稠密图;而邻接表多用于稀疏图
- 十字链表:“自己找自己”,外面的找前面是自己的,中间的找后面是自己的
- 十字链表通常是 3+4/5,邻接多重表通常是 2+5/6(若有权值,就会多一块)
图的基本操作
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
答案 | B | C | D | BD | BBD | B | A | A | D | |
序号 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ||
答案 | B | C | C | C | D | A | B | A |
-
C 选项,拓扑序列存在,一定不能是环
-
B
- 矩阵是几 x 几,顶点就有几个
-
D
【注🧨】邻接表有两部分: 顶点表和边表,若边表结点数为奇数,则图一定为有向图;若图为无向图,则边表结点数为偶数;若边表结点数为偶数,图不一定为无向图 -
C
- 题中的边表是不包括顶点表的。因为任何顶点 u u u 对应的边表中存放的都是以 u u u 为起点的边所对应的另一个顶点 v v v。从而 v v v 在边表中出现的次数也就是它的入度
- B
- 题目中说到最多,则该图为完全无向图,最多有 n ( n − 1 ) / 2 n(n-1)/2 n(n−1)/2 条边。每条边在邻接表中存储两次,因此边表结点最多为 n ( n − 1 ) n(n-1) n(n−1)
- A
- 建立图的邻接表需要遍历所有的顶点和边,每个顶点有一个顶点表结点,每条边需要创建一个边表结点并插入到相应的链表中。
- 因此,共需 n + 2 e n+2e n+2e 次操作,时间复杂度为 O ( n + e ) O(n+e) O(n+e)
- D
- BC 选项,比较邻接表和邻接矩阵的操作谁更简便,如果有比较,就不需要另一个的出现了
- C
- 矩阵不对称,为有向图,有向图的度为 row+col 下 1 的个数
图的遍历
- 从图中某一顶点出发,按照某种搜索方法沿着图中的边对图中所有顶点访问一次,且仅访问一次
- 图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础
- 为避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点,为此可以设一个辅助数组 visited[]来标记顶点是否被访问过
【注🧨】
- 对一个有 n 个顶点,e 条边的图采用邻接表表示时,进行 DFS 遍历的时间复杂度为 O ( n + e ) O(n+e) O(n+e),空间复杂度为 O ( e ) O(e) O(e);进行 BFS 遍历的时间复杂度为 O ( n + e ) O(n+e) O(n+e),空间复杂度为 O ( n ) O(n) O(n)
- 对有 n 个顶点、e 条边的图采用邻接矩阵表示时,进行 DFS 遍历的时间复杂度为 O ( n 2 ) O(n^2) O(n2),进行 BFS 遍历的时间复杂度为 O ( n 2 ) O(n^2) O(n2)
- [>] 广度优先搜索
广度优先搜索遍历图的过程是以 v v v 为起始点,由近至远依次访问和 v v v 有路径相通且路径长度为 1,2,… 的顶点。广度优先搜索是一种分层的查找过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样有往回退的情况,因此它不是一个递归的算法
- 为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问的顶点的下一层顶点
- 辅助数组 visited[] 标志顶点是否被访问过,其初始状态为 False
- 在图的遍历过程中,一旦某个顶点 v i v_i vi 被访问,就立即置 visited[i]为 True,防止它被多次访问
- [>] 深度优先搜索
深度优先搜索类似于树的先序遍历
- [!] 深度优先搜索步骤
- 从图中某个顶点 v v v 出发,访问 v v v
- 找出刚访问过的顶点的第一个未被访问的邻接点,访问该顶点。以该顶点为新顶点,重复此步骤,直至刚访问过的顶点没有未被访问的邻接点为止
- 返回前一个访问过的且仍有未被访问的邻接点的顶点,找出该顶点的下一个未被访问的邻接点,访问该顶点
- 重复步骤②和③,直至图中所有顶点都被访问过,搜索结束
- [!] 深度优先搜索效率分析
- 用邻接矩阵来表示图,遍历图中每一个顶点都要被从头扫描该顶点所在行,时间复杂度为 O ( n 2 ) O(n^2) O(n2)
- 用邻接表来表示图,虽然有 2 e 个表结点,但只需扫描 e 个结点即可完成遍历,加上访问 n n n 个头结点的时间,时间复杂度为 O ( n + e ) O(n+e) O(n+e)
- 结论
- 稠密图适于在邻接矩阵上进行深度遍历
- 稀疏图适于在邻接表上进行深度遍历
-
[>] 图的遍历和图的连通性
-
[!] 图的遍历算法可以用来判断图的连通性
- 对于无向图,若无向图是连通的,则从任意一个结点出发,仅需一次遍历就能够访问图中的所有顶点;若无向图是非连通的,则从某一个顶点出发,一次遍历只能访问到该顶点所在连通分量的所有顶点,而对于图中其他连通分量的顶点,则无法通过这次遍历访问
- 对于有向图来说,若从初始顶点到图中的每个顶点都有路径,则能够访问到图中的所有顶点,否则不能访问到所有顶点
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
答案 | B | D | A | A | D | BD | AD | |||
序号 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ||
答案 | D | C | B | C | D | D |
-
A
-
C
【方法💡】
①找相邻,不画图:a 相邻的 b,b 相邻的是 e,相邻的是 d, 故 A 错误,再走第二条边
②画图:(建议)
- 广度通常是比较扁平,而深度是狭长的,所以是 A
图的应用
应用-最小生成树
- 一个连通图的生成树包含图的所有顶点,并且只含尽可能少的边。
- 对于生成树来说,若砍去它的一条边,则会使生成树变成非连通图;若给它增加一条边,则会形成图中的一条回路
- 对于一个带权连通无向图 G,生成树不同,每棵树的权(即树中所有边上的权值之和)也可能不同
- 权值之和最小的那棵生成树称为 G 的最小生成树(MST)
- [>] 最小生成树性质
- 若图 G 中存在权值相同的边,则 G 的最小生成树可能不唯一,即最小生成树的树形不唯一。==当图 G 中的各边权值互不相等时,G 的最小生成树是唯一的;==若无向连通图 G 的边数比顶点数少 1,即 G 本身是一棵树时,则 G 的最小生成树是它本身
- 虽然最小生成树不唯一,但其对应的边的权值之和总是唯一的,而且是最小的
- 最小生成树的边数为顶点数减 1
- 最小生成树中所有边的权值之和最小,但不能保证任意两个顶点之间的路径是最短路径
构造最小生成树
主要利用性质:
- 假设 G = ( V , E ) G=(V,E) G=(V,E) 是一个带权连通无向图, U U U 是顶点集 V V V 的一个非空子集
- 若 ( u , v ) (u,v) (u,v) 是一条具有最小权值的边,其中 u ∈ U , v ∈ V − U u∈U,v∈V-U u∈U,v∈V−U,则必存在一棵包含边 ( u , v ) (u,v) (u,v) 的最小生成树
基于该性质的最小生成树算法主要有Prim和Kruskal算法,均是基于贪心算法的策略
通用算法:(实现途径:Prim 算法和 Kruskal 算法)-每次加入一条边以逐渐形成一棵生成树
GENERIC_MST(G){
T=NULL;
while T未形成一颗生成树;
do 找到一条最小代价边(u,v)并且加入T后不会产生回路;
T=T∪(u,v);
}
- [>] Prim 算法
- Prim (普里姆)算法的执行非常类似于寻找图的最短路径的 Dijkstra 算法
- 时间复杂度为 O ( ∣ V ∣ 2 ) O(|V|^2) O(∣V∣2),不依赖于 ∣ E ∣ |E| ∣E∣,适用于求解边稠密的图的最小生成树
- 采用其它方法能改进 Prim 算法的时间复杂度,但会增加实现的复杂性
- [!] 操作步骤:
- 初始时,从图中任取一顶点加入树 T,此时树中只有一个顶点
- 之后,选择一个与当前 T 中顶点集合距离最近的顶点,并将该顶点和相应的边加入 T,每次操作后 T 中的顶点数和边数都增 1
- 以此类推,直至图中所有的顶点都并入 T,得到的 T 就是最小生成树
- 此时 T 中必然有 n-1 条边
- [!] 伪码:
void Prim(G,T){
T=⊘; //初始化空树
U={w}; //添加任意一个顶点w
while ({V-U} !=⊘){ //若树中不含全部顶点
设(u,v)是使u∈U与v∈(V-U),且权值最小的边;
T=T∪{(u,v)}; //边归入树
U=U∪{v}; //顶点归入树
}
}
- [>] Kruskal 算法
- 与 Prim 算法从顶点开始扩展的最小生成树不同,Kruskal 算法是一种按权值的递增次序选择合适的边来构造最小生成树的方法
- 根据图相关性质,若一条边连接了两颗不同树种的顶点,则对这两颗树来说,它必定是连通的,将这条边加入森林中,完成两棵树的合并,直到整个森林合并成一棵树
- 通常采用堆来存放边的集合
- 算法的总时间复杂度为 O ( ∣ E ∣ l o g 2 ∣ E ∣ ) O(|E|{log}_2|E|) O(∣E∣log2∣E∣),不依赖于 ∣ V ∣ |V| ∣V∣,适用于边稀疏而顶点较多的图
- [!] 操作步骤:
- 初始时为只有 n 个顶点而无边的非连通图 T = V , { } T={V,\{\}} T=V,{},每个顶点自成一个连通分量
- 之后,按照边的权值由小到大的顺序,不断选取当前未被选取过且权值最小的边;若该边依附的顶点落在 T 中不同的连通分量上(此时指顶点)-(使用并查集判断这两个顶点是否属于同一颗集合树),则将此边加入 T;否则舍弃此边选择下一条权值最小的边
- 以此类推,直至 T 中所有顶点都在一个连通分量上
- 图上 e 和 f 暂未理解 #done 不允许构成回路
- [!] 伪码
应用-最短路径
- 广度优先搜索查找最短路径只针对无权图
- 带权图时:把从一个顶点 v 0 v_0 v0 到图中其余任意一个顶点 v i v_i vi 的一条路径所经过边上的权值之和,定义为该路径的带权路径长度,把带权路径长度最短的那条路径(可能不止一条)称为最短路径
求解最短路径
主要利用性质:
- 两点之间的最短路径也包含了路径上其他顶点间的最短路径
带权有向图 G 的最短路径问题有两类:
- 求单源最短路径:求图中某一顶点到其他各顶点的最短路径,可用算法==Dijkstra (迪杰斯特拉)==求解
- 求每对顶点间的最短路径,可用算法Floyd(弗洛伊德)
- [>] D i j k s t r a Dijkstra Dijkstra 算法求解单源最短路径
- 算法设置一个集合 S 记录已求得的最短路径的顶点,初始时把源点 v 0 v_0 v0 放入 S,集合 S 每并入一个新顶点 v i v_i vi,都要修改源点 v 0 v_0 v0 到集合 V-S 中顶点当前的最短路径长度值
- Dijkstra 算法也是基于贪心策略的
- 在构造的过程中还设置了三个辅助数组:
- final[]: 标记各顶点是否已经找到最短路径,即是否归入集合 S
- dist[]: 记录从源点 v 0 v_0 v0 到其他各顶点当前的最短路径长度,它的初始值为:若从 v 0 v_0 v0 到 v i v_i vi 有弧,则 dist[i]为弧上的权值;否则值 dist[i]为∞
- path[]:path[i]表示从源点到顶点 i 之间的最短路径的前驱结点。在算法结束时,可根据其值追溯得到源点 v 0 v_0 v0 到顶点 v i v_i vi 的最短路径
- 例如,假设从顶点 0 出发,即 v 0 = 0 v_0=0 v0=0,集合 S 最初只包含顶点 0,邻接矩阵 arcs 表示带权有向图, a r c s [ i ] [ j ] arcs[i][j] arcs[i][j] 表示有向边<i,j>的权值,若不存在有向边<i,j>, 则 a r c s [ i ] [ j ] arcs[i][j] arcs[i][j] 为∞
- [!] 操作
- 初始化:集合 S 初始为{0},dist[]的初始值 d i s t [ i ] = a r c s [ 0 ] [ i ] , i = 1 , 2 , . . . , n − 1 dist[i]=arcs[0][i], i=1,2,..., n-1 dist[i]=arcs[0][i],i=1,2,...,n−1
- 从顶点集合 V-S 中选出 v j v_j vj,满足 d i s t [ j ] = M i n { d i s t [ i ] ∣ v i ∈ V − S } dist[j]=Min\{dist[i]|v_i∈V-S\} dist[j]=Min{dist[i]∣vi∈V−S}, v j v_j vj 就是当前求得的一条从 v 0 v_0 v0 出发的最短路径的终点,令 S = S ∪ { j } S=S∪\{j\} S=S∪{j}
- 修改从 v 0 v_0 v0 出发到集合 V-S 上任意一个顶点 v k v_k vk 可达的最短路径长度;若 d i s t [ j ] + a r c s [ j ] [ k ] < d i s t [ k ] dist[j]+arcs[j][k]<dist[k] dist[j]+arcs[j][k]<dist[k], 则更新 d i s t [ k ] = d i s t [ j ] + a r c s [ j ] [ k ] dist[k]=dist[j]+arcs[j][k] dist[k]=dist[j]+arcs[j][k]
- 重复步骤 2 和 3 操作共 n-1 次,直到所有的顶点都包含在集合 S 中
-
[!] 时间复杂度: O ( ∣ V ∣ 2 ) O(|V|^2) O(∣V∣2),且对于边上带有负权值时,此算法并不适用
-
[!] Dijkstra 算法和 Prim 算法异同
- 同:两个算法的流程、操作相似,且都基于贪心策略
- 异:①目的不同,Dijkstra 算法的目的是构建单源点的最短路径树;Prim 算法的目的是构建最小生成树。②算法思路略有不同,Prim 算法从一个点开始,每次选取权值最小的边,将其连接到已构建的生成树上,直至所有顶点都已加入,而 Dijkstra 算法每次找出到源点距离最近且未归入集合的点,并把它归入集合,同时以这个点为基础更新从源点到其他所有顶点的距离。③适用的图不同,Prim 算法只能用于带权无向图;Dijkstra 算法可用于带权有向图或带权无向图。④时间复杂度不同
- [>] Floyd 算法求各顶点之间最短距离
求所有顶点之间的最短路径问题描述如下:已知一个各边权值均大于 0 的带权有向图,对任意两个顶点 v i ≠ v j v_i≠v_j vi=vj,要求求出 v i v_i vi 与 v j v_j vj 之间的最短路径和最短路径长度
-
[!] 算法基本思想
-
Floyd 算法时间复杂度为 O ( ∣ V ∣ 3 ) O(|V|^3) O(∣V∣3)
-
Floyed 算法允许图中有带负权值的边,但不允许有包含带负权值的边组成的回路
-
Floyd 算法同样适用于带权无向图,因为带权无向图可视为权值相同往返二重边的有向图
-
若用 Dijkstra 算法求解此类问题时,其复杂度为 O ( ∣ V ∣ 2 ) ∣ V ∣ = O ( ∣ V ∣ 3 ) O(|V|^2)|V|=O(|V|^3) O(∣V∣2)∣V∣=O(∣V∣3)
-
[>] BFS 算法、Dijkstra 算法和 Floyd 算法求最短路径总结
应用-有向无环图描述表达式
在表达式的有向无环图表示中,不可能出现重复的操作数顶点
应用-拓扑排序
- AOV 网:若用有向无环图表示一个工程,其顶点表示活动,用有向边 < V i , V j > <V_i,V_j> <Vi,Vj> 表示活动 V i V_i Vi 必须先于活动 V j V_j Vj 进行的一种关系,则将这种有向图称为顶点表示活动的网络,简称 AOV 网
- 拓扑排序:在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序:①每个顶点出现且只出现一次,②若顶点 A 在序列中排在顶点 B 的前面,则在图中不存在从 B 到 A 的路径
- 拓扑排序是对有向无环图的顶点的一种排序,它使得若存在一条从顶点 A 到顶点 B 的路径,则在排序中 B 出现在 A 的后面。
- 每个 AOV 网都有一个或多个拓扑排序序列
- [>] 对一个 AOV 网进行拓扑排序算法步骤:
- 每轮从 AOV 网中选择一个没有前驱(入度为 0)的顶点并输出
- 从网中删除该顶点和所有以它为起点的有向边
- 重复①和②直到当前的 AOV 网为空或当前网中不存在无前驱的顶点为止,后一种情况说明有向图中必然存在环
- [>] 时间复杂度
- 邻接表存储方式下的拓扑排序效率: O ( ∣ V ∣ + ∣ E ∣ ) O(|V|+|E|) O(∣V∣+∣E∣)
- 邻接矩阵存储方式下的拓扑排序效率: O ( ∣ V ∣ 2 ) O(|V|^2) O(∣V∣2)
应用 -逆拓扑排序
- [>] 操作步骤
- 从 AOV 网中选择一个没有后继(出度为 0)的顶点并输出
- 从网中删除该顶点和所有以它为终点的有向边
- 重复①和 2 直到当前 AOV 网为空
【注意🧨】用拓扑排序算法处理 AOV 网时:
- 入度为零的顶点,即没有前驱活动的或前驱活动都已经完成的顶点,工程可用从这个顶点所代表的活动开始或继续
- 若一个顶点有多个直接后继,则拓扑排序的结果通常不唯一;但若各个顶点已经排在一个线性有序的序列中,每个顶点有唯一的前驱后继关系,则拓扑排序的结果是唯一的
- AOV 网中各顶点的地位平等,每个顶点编号是人为的,因此可以按拓扑排序的结果重新编号,生成 AOV 网的新的邻接存储矩阵,这种邻接矩阵可以是三角矩阵;但对一般的图来说,若其邻接矩阵是三角矩阵,则存在拓扑序列,反之则不一定成立
应用-关键路径
- AOE 网:带权有向图,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销,称之为用边表示活动的网络,简称 AOE 网
- AOE 网和 AOV 网都是有向无环图,区别在于它们的边和顶点所代表的含义不同,AOE 网中的边有权值;而 AOV 网中的边无权值,仅表示顶点之间的前后关系
- [>] AOE 网性质
- 当某顶点事件发生后,从该顶点出发的各有向边所代表的活动才能开始
- 只有在进入某顶点的各有向边所代表的活动都已经结束时,该顶点所代表的事件才能开始
- 在 AOE 网中仅有一个入度为 0 的顶点,称为开始顶点(源点)它表示整个工程的开始;也仅有一个出度为 0 的顶点,称为结束顶点(汇点),表示整个工程的结束
- AOE 网中有些活动是可以并行进行的
- [!] 关键路径
- 从源点到汇点的所有路径中,具有最大路径长度的路径称为关键路径,把关键路径上的活动称为关键活动
- 完成整个工程的最短时间就是关键路径的长度,即关键路径上各活动花销的总和
- 若关键活动不能按时完成,则整个工程的完成时间就会延长。因此,只要找到了关键活动,就找到了关键路径,也就可以得出最短完成时间
l ( i ) − e ( i ) = 0 l(i)-e(i)=0 l(i)−e(i)=0 即 l ( i ) = e ( i ) l(i)=e(i) l(i)=e(i) 的活动 a i a_i ai 是关键活动
- [!] 缩短工期
- 关键路径上的所有活动都是关键活动,可以通过加快关键活动来缩短整个工程的工期。但也不能任意缩短关键活动,因为一旦缩短到一定的程度,该关键活动就可能会变成非关键活动
- 网中的关键路径不唯一,且对于有多条关键路径的网,只提高一条关键路径上的关键活动速度并不能缩短整个工程的工期,只有加快所有在关键路径上的关键活动才能达到缩短工期的目的
- [!] 图算法在采用不同存储方式时的时间复杂度
小节选择题答案
序号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
答案 | A | C | A | D | B | C | A | C | B | D | D | |
序号 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
答案 | D | B | B | C | C | C | B | |||||
序号 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
答案 | C | D | C | C | C | C | D | C | C | B | B | |
序号 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ||
答案 | D | C | B | A | B | A | D | B | A |
- A
- 只要无向连通图中没有权值相同的边,则其最小生成树唯一
- A
- 设有 n 个顶点的无向连通图的最小生成树不唯一,则图的边数一定大于 n-1
-
A
-
C
- Kruskal 算法顶点间不能构成回路
- C
- Dijkstra 算法对每对顶点间的最短路径的时间复杂度为 O ( n ∗ n 2 ) = O ( n 3 ) O(n*n^2)=O(n^3) O(n∗n2)=O(n3)
- D
- 这种类型题,因为已经求得最短路径集合,那他就不会再更改,所以选 1,修改它本身就行
- A
- 判断一个有向图是否有环(回路),方法:深度优先遍历、拓扑排序、求最短路径(若无该答案,只选前两个方法)
- D
- [!] 关于拓扑排序:
- 若某有向图存在环路,则该有向图一定不存在拓扑排序
- 在拓扑排序算法中为暂存入度为零的顶点,可以使用栈也可以使用队列
- 若有向图的拓扑有序序列唯一,则图中入度为 0 和出度为零的顶点都仅有 1 个
- 强连通图不能进行拓扑排序
- 若一个有向图的顶点不能排成一个拓扑序列,则判定该有向图含有顶点数大于 1 的强连通分量
- 若一个有向图具有有序的拓扑排序序列,则它的邻接矩阵必定为三角矩阵
- 若用邻接矩阵存储有向图,矩阵中主对角线以下的元素均为零,则该图拓扑序列存在,可能不唯一
- 错误说法:
- 若有向图的拓扑有序序列唯一,则图中每个顶点的入度和出度最多为 1
- 在一个有向图的拓扑序列中,若顶点 a 在顶点 b 之前,则图中必有一条弧<a,b>
- 若一个有向图的顶点不能排成一个拓扑序列,则判定该有向图含有多个出度为 0 的顶点、或判定该有向图是个强连通分量、或判定该有向图含有多个入度为 0 的顶点
- 若有向无环图的拓扑序列唯一,则可以唯一确定该图
- B
- 无向图的邻接矩阵是对称矩阵
- C
-
[!] 关于关键路径:
-
求关键路径是以拓扑排序为基础的
-
任何一个活动的持续时间的改变可能会影响关键路径的改变
-
一个事件的最早发生时间与以该事件为始的弧的活动的最早开始事件相同
-
在 AOE 图中,关键路径上活动的时间延长多少,整个工期也就随之延长多少
-
缩短所有关键路径上共有的任意一个关键活动的持续时间可缩短关键路径长度
-
错误说法:
-
改变网上某一关键路径上的任意一个关键活动后,必将产生不同的关键路径
-
缩短关键路径上任意一个关键活动的持续时间可缩短关键路径长度
-
缩短多条关键路径上共有的任意一个关键活动的持续时间可缩短关键路径长度
-
一个事件的最迟发生时间是以该事件为尾的弧的活动的最迟开始时间与该活动的持续时间的差
- A
- 邻接矩阵第 i 列值全为∞,说明顶点 i 没有入边,为整个工程的开始,若关键路径存在,则该顶点一定是起点。不能确定关键路径是否存在,也不能确定其对应的无向图的连通分量个数
-
B
-
A
-
[!] 关于最小生成树:
-
最小生成树代价唯一
-
错误说法:
-
所有权值最小的边一定会出现在所有的最小生成树中
-
使用 Prim 算法从不同顶点开始得到的最小生成树一定相同
-
使用 Prim 算法和 Kruskal 算法得到的最小生成树总不相同
-
A
-
B #todo暂未理解
-
C
-
B
-
B
- 已知无向连通图 G 中各边的权值均为 1. 在下列算法中,一定能够求出图 G 中从某顶点到其余各顶点最短路径的是:图的广度优先搜索算法,走了几步,最短路径就是几
- Prim 算法和 Kruskal 算法是求最小生成树的算法