![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
最短路径问题
文章平均质量分 73
Miracle 007
这个作者很懒,什么都没留下…
展开
-
最短路径算法对比分析
我们选择最短路径算法时,要根据实际需求和每一种算法的特性,选择合适的算法。Floyd算法虽然总体时间复杂度高,但是可以处理带有负权边的图(但不能含有负权回路)并且均摊到每一点的对上,在所有的算法中还是属于较优的。另外Floyd算法较小的编码复杂度也是它的一大优势。所以,如果要求的是所有点对间的最短路径,或者数据范围较小,则Floyd算法比较适合。Dijkstra算法最大的弊端是它无法处理带有负权边已经负权回路的图,但是Dijkstra算法具有良好的课扩展性,扩展后可以适应很多问题。另外用堆优化的Dij.原创 2021-02-09 12:56:27 · 619 阅读 · 0 评论 -
Bellman-Ford算法的队列优化
算法优化核心思维:每次仅对发生变化了的点的相邻边执行松弛操作。但是如何知道当前哪些点的最短路径发生了变化呢?这里可以用一个队列来维护这些点,算法大致如下:每次选取队首顶点u,对顶点u的所有边进行松弛操作。例如有一条u->v的边,如果通过u->v这条边使得源点到顶点v的最短路程变短(dis[u] + e[u][v] < dis[v]),且顶点v不在当前的队列中,我们就将顶点v放入队尾。需要注意的是,同一个顶点同时在队列中出现多次是毫无意义的,所以我们需要一个数组来判重(判断哪些点已经在队原创 2021-02-09 12:31:23 · 425 阅读 · 1 评论 -
Bellman-Ford算法(解决负权边)
核心代码:for (int k = 1; k <= n - 1; ++k){ for (int i = 1; i <= m; ++i){ if(dis[v[i]] > dis[u[i]] + w[i]) dis[v[i]] = dis[u[i]] + w[i]; }} 上面的代码外层循环一共循环了n - 1次(n为顶点个数), 内层循环循环了m次(m为每一条边),即枚举每一条边。dis数组的作用与Dijkstra算法一样,是用来记录源点到其余各个顶点的最短路径的。u、原创 2021-02-09 10:07:31 · 597 阅读 · 1 评论 -
Dijkstra算法(单源最短路)
1.储存这里仍用一个二维数组来储存顶点之间边的关系。除此之外,我们还需要一个dis数组来储存1号顶点到其余各个顶点的初始路程。如:dis = {0,1,12,inf,inf,inf}(这里inf是无穷大)我们将此时dis数组中的值称为最短路径的“估计值”(没有计算过最短路径之前1号顶点到其余各点之间的路程)。2.松弛既然是计算1号顶点到其余各点之间的最短路程,那就先找一个离1号顶点最近的顶点。通过数组可知离1号顶点最近的顶点是2号顶点。接下来看2号顶点有哪些出边呢?有2->3和2->4原创 2021-01-29 20:46:42 · 286 阅读 · 0 评论 -
Floyd-Warshall算法(多源最短路径问题)
1.用一个二维数组存储图的信息。如:map[1][2] = 2,表示1号城市 到2号城市的路程是2。注意:1.两个城市之间如果没有路,则设两个城市之间的路程为无穷大(inf)2.一个城市到自己的路程是0.如:map[1][1] = 0.3.这些公路是单向的2.思想:根据以往的经验,如果要让任意两个点(例如从顶点a到顶点b)之间的路程变短,只能引入第三个点(顶点k),并通过这个顶点k中转,即:a->k->b,才可能缩短原来从顶点a到顶点b的路程。那么这个中转顶点k是1~n中的哪一个呢原创 2021-01-29 11:32:43 · 296 阅读 · 0 评论