Day62 - 图论 Part11

22 阅读3分钟

激动,终于最后一天了。

基础

刷题

  1. 小明逛公园

kamacoder.com/problempage…

image.png

Floyd算法 (弗洛伊德算法)

Floyd算法主要是动态规划的思路。这里使用动规五部曲:

  • 确定dp数组

// 使用邻接矩阵存储 grid = make([][]int, n+1) // dp数组是一个三维数组,在grid上加一个维度k,grid[k][i][j], k是起点为i,终点为j, // 中间可以经过[1-k] 中转的路径中的最短路径。 dp = make([][][]int, n+1)

//当然dp数组是可以压缩的 dp = make([][]int, n+1)

  • 确定dp数组递推公式

dp[k][i][j] = min(dp[k-1][i][j], dp[k-1][i][k], dp[k-1][k][j])

// 压缩 dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j])

  • 确定dp数组初始化

先存储dp[0], 也就是输入的邻接矩阵,其他初始化为math.MaxInt32

  • 确定dp数组遍历顺序

k 从1到n

  • 打印dp数组
  1. 骑士的攻击

kamacoder.com/problempage…

image.png

本题主要是使用A算法,是广搜算法的优化版本,主要是通过G,H,F三个参数来寻找 F 最短的那一个(使用堆优化队列),F是A算法中,对最优节点的计算方法,F= G+H

  • G = 从起点到该节点路径消耗
  • H = 该节点到终点的预估消耗

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

其实只是场景不同而已 我们在搜索最短路的时候, 如果是无权图(边的权值都是1) 那就用广搜,代码简洁,时间效率和 dijkstra 差不多 (具体要取决于图的稠密)

如果是有权图(边有不同的权值),优先考虑 dijkstra。

总结

最短路径

最短路径的算法总结,dijkstra,dijkstra堆优化版本,bellman_ford, SPFA,floyd算法,A star属于启发式搜索,与前面几种算法不是同一种类型。

www.programmercarl.com/kamacoder/%…

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

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

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

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

并查集

  • 并查集解决的问题

两个节点在不在同一个集合,如何将2两个节点放入同一个集合

  • 并查集原理以及代码实现

  • 并查集写法的常见误区

在join的时候,不是合并的根结点

最小生成树

两个算法: prim算法 和 kruskal 算法

Prim算法三部曲:

  • 寻找距离最小生成树最近的节点
  • 加入最小生成树
  • 更新非最小生成树节点 到最小生成树的距离(更新minDist数组)

kruskal 算法:

  • 把所有的边排序,找到权值最小的那条边,加入到最小生成树中
  • 遍历未加入到最小生成树的边,使用并查集
    • 如果边左右两个节点都在最小生成树中,那么就形成了环
    • 如果边左右两个节点不在一个集合,加入最小生成树

拓扑排序

给出一个 有向图,把这个有向图转成线性的排序 就叫拓扑排序

对于有向图,可以把a指向b,看作b依赖于a,需要执行b,必须要先完成a

拓扑排序的一些应用场景,例如:大学排课,文件下载依赖 等等。

解题两个步骤:

  • 找到入度为0的节点,加入结果集
  • 删掉该节点为头的边,再次寻找入度为0的节点

代码随想录 一刷,完结撒花!