题目一

涉及考点
邻接矩阵
方便找到是否有边 顶点的度
但是空间复杂度高 对于统计边的数量只能枚举

入度:竖 出度:横
邻接表


深度优先搜索 DFS
基于栈的访问
算法复杂度
时间复杂度:O(n) 每个节点都被访问
空间复杂度:最坏O(n)。AVL树O(logn)
用于生成括号-子集枚举-N皇后问题
搜索所有可能路径
广度优先搜索 BFS
基于队列的访问
先进先出-离得近的先访问
算法复杂度

空间复杂度:对于平衡二叉树,一般存入队列的是一层的内容,不超过树高logn;对于普通搜索树则是O(N)
题目与解析









题目二

涉及考点
克鲁斯卡尔最小生成树ElogE
创建并查集类
包括find check两个函数,check通过find找到两个连通分支各自的代表元
如果一致则返回false,否则true
在主函数中,创建目标队列 与 uf对象
对每一条边遍历,根据权重排序,每次提取最小的边,
对其顶点进行判断,调用uf对象的check函数,如果返回true则证明为两个分支,可以选择,否则continue
直到n-1
这就设计了连通性判断,因此需要上面并查集的内容

这样的操作包括:
1.判断是否成环------是否联通 root_x=self.find(x) root_y=self.find(y) root_x == root_y?
2.将一条边加入生成树中------union()
先创建UF集合,会自动拆为最小节点
然后堆边进行sort 复杂度logE,然后对于每条边进行判断:
如果uf.union能够执行,也就是UF输出True,不成环的情况下,就往mst中添加这条边,同时累加权重
直到mst的len=n-1


时间复杂度:

Prim最小生成树算法ElogV
创建邻接表、最小堆 目标队列 已访问 原始节点队列
创建结构体 包括起点 终点 权重
遍历所有边将其连接的点存入邻接表
初始时选择任意一个节点,探索其边,选择最小权重边,查看邻接表其终点是否在已访问列表中
如果没有则添加,并累计权重
同时将邻居节点的相邻边放入最小堆

开辟最小堆,维护当前可用探索的边,由于每次探索最小的,因此使用最小堆
开辟结果列表维护选取的边
开辟以访问集保存已经访问的顶点
开辟nodes集保存未访问的节点
'

nodes用于存放当前可用访问的节点
visited存放已经访问的顶点
mst保存结果边 weight保存总权重
min_heap维护当前可选边
对于传入的每一条边,对于第一个顶点graph[u]添加权重为w,目的为v
对于第二个顶点graph[v]添加权重为w,目的为u

随机选一个起点。
将其放入已访问列表visited,然后把start顶点可连出去的所有边放入最小堆,堆会自动按权重从小到大排序
对于每一轮,取出堆中最小的边,如果其目标顶点没有访问过,就将其添加到visied中,然后将这条边放进mst目标列表中,同时累加权重
对于这条新加入顶点考虑,对于新顶点的其他边连接的节点,如果没有访问过,就全部放入堆中
直到n-1条边都被访问了
时间复杂度:
对于堆的处理复杂度都是logV 每条边最多被加入堆一次,因此堆操作数不超过E次,因此复杂度是O(ElogV)
题目与解析









题目三

涉及考点
单元最短路 BellmanFord(可解决负权边)
依次遍历所有节点的所有边,即A->B A->C A->D,然后B->E C->B C->E。。。
重复V-1轮一定收敛,可能提前收敛

算法复杂度:O(V*E)
性质


要做V-1次遍历,因为有V-1条边
每一轮要松弛所有的边

要做多少轮?V-1







检测负环是否存在?
更新到第V-1次后收敛,不再更新。
为什么要V-1条边?
因为任意两个节点的最短路径最多包含V-1条边,如果出现环说明两条路必定存在一最短路。
题目与解析

一句话就是:列边松弛列DPi
列出所有可达边,然后一直松弛,遍历所有边后列DΠ表





最多需要遍历最短路径长度的边的轮数,每轮复杂度E



题目四
涉及考点
带虚拟节点的单源最短路
OJ作业有一道灌溉农田的题基本一样,这里把抽水机的价格换位等待时间即可
题目与解析


题目五
涉及考点
Floyd-Warshall 动态规划(来源数据结构)
D法是单源算法,如果要全源则需要n次
FW能一次性计算出所有点之间的最短路径
通过一张加权表和一张前驱表不断更新得到
distx是邻接矩阵,表达任意两点之间的最短距离
nextx是前驱表,记录下一跳
通过三层循环,选择kij,k是中继节点,i是起始,j是终点
不断更新k,相当于在任意两个节点之间插入另一个节点,看看有没有更短通路
更新n轮后一定会收敛
只要对角线为正,就证明没有负权环

对于最终表,从2->3,先看next4,由0,为下一条,那么下一步就是0->3,是1,然后是1->3,找到最短路径2-0-1-3. 距离是dist4 2->3=4
算法复杂度:

Floyd-Warshall 算法(来源算法设计)
对于01背包好用,物品当作节点







题目与解析
技巧:
1.k=1和k=4时可以用瞪眼法

2.k=1时 第一行 k=4时第四行不用更新
3.当(a,b+c)结构的b为0或无穷时不用更新






很简单,就是把在这个算法上多加一个前驱矩阵即可,用vector套vector初始化一个二维矩阵,然后D<-W初始化要额外说明对Pi的初始化。后面就是常规的FW。空间就是V*V



