代码随想录算法训练营第62天 | Floyd 算法精讲、A * 算法精讲 (A star算法)、最短路算法总结篇、图论总结

Floyd 算法精讲

题目链接/文章讲解:https://www.programmercarl.com/kamacoder/0097.%E5%B0%8F%E6%98%8E%E9%80%9B%E5%85%AC%E5%9B%AD.html

解题思路

  1. 确定dp数组(dp table)以及下标的含义

这里我们用 grid数组来存图,那就把dp数组命名为 grid。

gridijk = m,表示 节点i 到 节点j 以1...k 集合中的一个节点为中间节点的最短距离为m

节点i 到 节点j 的最短路径中 一定是经过很多节点,那么这个集合用1...k 来表示。

  1. 确定递推公式

我们分两种情况:

  1. 节点i 到 节点j 的最短路径经过节点k
  2. 节点i 到 节点j 的最短路径不经过节点k

对于第一种情况,grid[i][j][k] = grid[i][k][k - 1] + grid[k][j][k - 1]

节点i 到 节点k 的最短距离 是不经过节点k,中间节点集合为1...k-1,所以 表示为grid[i][k][k - 1]

节点k 到 节点j 的最短距离 也是不经过节点k,中间节点集合为1...k-1,所以表示为 grid[k][j][k - 1]

第二种情况,grid[i][j][k] = grid[i][j][k - 1]

如果节点i 到 节点j的最短距离 不经过节点k,那么 中间节点集合1...k-1,表示为 grid[i][j][k - 1]

因为我们是求最短路,对于这两种情况自然是取最小值。

即: grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1])

  1. dp数组如何初始化

gridijk = m,表示 节点i 到 节点j 以1...k 集合为中间节点的最短距离为m。

刚开始初始化k 是不确定的。

所以 只能 把k 赋值为 0,本题 节点0 是无意义的,节点是从1 到 n。

这样我们在下一轮计算的时候,就可以根据 gridij0 来计算 gridij1,此时的 gridij1 就是 节点i 经过节点1 到达 节点j 的最小距离了。

所以初始化代码:

复制代码
vector<vector<vector<int>>> grid(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 10005)));  // C++定义了一个三位数组,10005是因为边的最大距离是10^4

for(int i = 0; i < m; i++){
    cin >> p1 >> p2 >> val;
    grid[p1][p2][0] = val;
    grid[p2][p1][0] = val; // 注意这里是双向图
} 
  1. 确定遍历顺序

从递推公式:grid[i][j][k] = min(grid[i][k][k - 1] + grid[k][j][k - 1], grid[i][j][k - 1]) 可以看出,我们需要三个for循环,分别遍历i,j 和k

而 k 依赖于 k - 1, i 和j 的到 并不依赖与 i - 1 或者 j - 1 等等。

所以遍历k 的for循环一定是在最外面,这样才能一层一层去遍历。

  1. 举例推导dp数组

A * 算法精讲 (A star算法)

题目链接/文章讲解:https://www.programmercarl.com/kamacoder/0126.%E9%AA%91%E5%A3%AB%E7%9A%84%E6%94%BB%E5%87%BBastar.html

解题思路

Astar 是一种 广搜的改良版。 有的是 Astar是 dijkstra 的改良版。

而 Astar 关键在于 启发式函数, 也就是 影响 广搜或者 dijkstra 从 容器(队列)里取元素的优先顺序。

BFS 是没有目的性的 一圈一圈去搜索, 而 A * 是有方向性的去搜索

对队列里节点进行排序,就需要给每一个节点权值,如何计算权值呢?

每个节点的权值为F,给出公式为:F = G + H

G:起点达到目前遍历节点的距离

H:目前遍历的节点到达终点的距离

起点达到目前遍历节点的距离 + 目前遍历的节点到达终点的距离 就是起点到达终点的距离。

计算出来 F 之后,按照 F 的 大小,来选去出队列的节点。

可以使用 优先级队列 帮我们排好序,每次出队列,就是F最小的节点。

最短路算法总结篇

题目链接/文章讲解:https://www.programmercarl.com/kamacoder/%E6%9C%80%E7%9F%AD%E8%B7%AF%E9%97%AE%E9%A2%98%E6%80%BB%E7%BB%93%E7%AF%87.html

了解最短路算法和使用场景。

至此已经讲解了四大最短路算法,分别是Dijkstra、Bellman_ford、SPFA 和 Floyd。

如果遇到单源且边为正数,直接Dijkstra

至于 使用朴素版还是 堆优化版 还是取决于图的稠密度。

如果遇到单源边可为负数,直接 Bellman-Ford,同样 SPFA 还是 Bellman-Ford 取决于图的稠密度。

如果有负权回路,优先 Bellman-Ford, 如果是有限节点最短路 也优先 Bellman-Ford,理由是写代码比较方便。

如果是遇到多源点求最短路,直接 Floyd

图论总结

题目链接/文章讲解:https://www.programmercarl.com/kamacoder/%E5%9B%BE%E8%AE%BA%E6%80%BB%E7%BB%93%E7%AF%87.html

了解图的存储方式,邻接表和邻接矩阵

了解深搜与广搜在图这个数据结构上的搜索过程

了解并查集的应用

了解最小生成树

了解拓扑排序

了解最短路算法

总结

第62天,完结

相关推荐
Jerry17 分钟前
KeetCode 58. 区间和
算法
Jerry1 小时前
LeetCode 209. 长度最小的子数组
算法
彦为君1 小时前
算法思维与经典智力题
java·前端·redis·算法
智能优化与强化学习2 小时前
Gym(Gymnasium)仿真环境详解(二):环境简介、入门算法、调参要点、核心挑战
算法·强化学习·gym·零基础入门·算法评估
mxwin2 小时前
Unity Shader exp 函数的算法与渲染应用
算法·unity·游戏引擎·shader
“码”力全开2 小时前
AI视频分析误报优化完整流程
算法·架构·边缘计算
深盾科技_Virbox2 小时前
深盾科技·Virbox产品体系全景解读:软件安全如何从加密锁走向全生命周期
java·大数据·算法·安全·软件需求
可编程芯片开发3 小时前
基于VSG虚拟同步发电机控制的三相并网逆变器带多组可变负载Simulink建模与仿真
算法
AI服务老曹3 小时前
国产NPU视觉算法参数配置说明
算法·性能优化·边缘计算
彦为君3 小时前
Redis最新版本特性
java·数据库·redis·算法·bootstrap