【图论】最短路径

本文为图论的学习总结,讲解最短路径算法。

当边的权值全相同时,我们可以从起点出发对图进行 BFS,遇到终点时停止。由此得到的广度优先生成树上,从根节点到终点节点就是中转次数(即总权值)最少的路径。

但实际情况中,边的权值不完全相同,我们通常这个问题分为两类,一种是从某个源点到其余各顶点的最短路径(单源),另一种是每一对顶点间的最短路径(多源)。

单源

迪杰斯特拉

首先将起点放入集合 SS,对其余各点标记起点到该点的最小距离和路径。找一条从 SS 中出去的最短边加入边集 EE,将边的终点加入 SS,并更新各点标记。不断重复直到所有点都被标记。

【图论】最短路径

编程实现见【Dijkstra 算法】,算法复杂度为 O(n2)O(n^2)

其他算法

其他算法如 Bellman Ford、SPFA、堆优化的 Dijkstra 等见【单源最短路径】、【A* 算法】、【模拟退火算法】、【遗传算法】。

多源

弗洛伊德

如果将 Dijkstra 算法重复 nn 次也可以进行求解,Floyd 算法形式上更加简单。

(vi,,vk)(v_i,…,v_k)(vk,,vj)(v_k,…,v_j) 分别是从 viv_ivkv_k 和从 vkv_kvjv_j 的中间顶点序号不大于 k1k-1 的最短路径,则将 (vi,,vk,,vj)(v_i,…,v_k,…,v_j) 和已经得到的从 viv_ivjv_j 且中间顶点序号不大于 k1k-1 的最短路径相比较,较短者就是从 viv_ivjv_j 的中间顶点序号不大于 kk 的最短路径。经过 kk 次比较后,最后求得的必是 viv_ivjv_j 的最短路径。

编程实现见【Floyd 算法】,算法复杂度为 O(n3)O(n^3)

旅行商问题

见【哈密顿回路】。

有帮助的话点个赞加关注吧