小M带你学最短路

目录

总起

Dijkstra算法

Floyd-Warshall算法

Bellman-Ford算法

SPFA算法

题外话

引入正题

总结


总起

图论中的最短路问题是指在一个图中寻找从一个起点到某个终点的路径中最短的路径。最短路径可以通过不同的方式来定义,比如可以是路径的长度最短,或者是路径中经过的边的数量最少。

在图论中,最短路问题可以通过使用不同的算法来解决。以下是一些常用的算法:

1. Dijkstra算法:Dijkstra算法是一种贪心算法,用于解决带权重的有向图中的最短路问题。该算法通过计算起点到图中所有其他顶点的最短距离,并利用此信息来确定最短路径。

2. Floyd-Warshall算法:Floyd-Warshall算法用于解决带权重的有向图中的所有顶点之间的最短路问题。该算法通过计算任意两个顶点之间的最短距离,以及路径上的中间顶点,从而确定最短路径。

3. Bellman-Ford算法:Bellman-Ford算法是一种动态规划算法,用于解决带权重的有向图中的单源最短路问题。该算法通过迭代计算从起点到其他所有顶点的最短距离,并使用此信息来确定最短路径。

这些算法都有不同的时间复杂度和适用范围。在实际应用中,需要根据具体的问题和图的规模选择合适的算法来解决最短路问题。

Dijkstra算法

Dijkstra算法是一种用于解决带权重的有向图中的单源最短路问题的贪心算法。它可以找到从一个起点到图中其他所有顶点的最短路径。

算法的基本思想是:
1. 初始化起点的距离为0,其他所有顶点的距离为无穷大。
2. 创建一个优先队列(通常使用最小堆实现),用于存储待处理的顶点。
3. 从起点开始,把起点加入优先队列中,并将起点的距离设为0。
4. 循环以下步骤,直到优先队列为空:
   a. 从优先队列中取出距离最小的顶点,设为当前顶点。
   b. 遍历当前顶点的所有邻居顶点,计算经过当前顶点到达邻居顶点的距离(当前顶点的距离加上边的权重),并将该距离与邻居顶点的当前最短距离进行比较。
   c. 如果计算得到的距离小于邻居顶点的当前最短距离,则更新邻居顶点的最短距离,并将邻居顶点加入优先队列。
5. 重复步骤4,直到优先队列为空

最终,通过该算法计算得到的起点到达所有其他顶点的最短路径长度,以及路径上的中间顶点,可以用于构建最短路径树或生成具体的最短路径。

Dijkstra算法的时间复杂度取决于实现方式,如果使用最小堆来实现优先队列,其时间复杂度为O((V+E)logV),其中V为顶点数,E为边数。

Floyd-Warshall算法

Floyd-Warshall算法是一种用于解决带权重的有向图中的所有顶点对最短路问题的动态规划算法。它可以找到任意两个顶点之间的最短路径长度。

算法的基本思想是:
1. 创建一个二维数组dist,用于存储任意两个顶点之间的最短路径长度。初始化dist数组,使得dist[i][j]表示从顶点i到顶点j的直接距离(如果有边连接)或无穷大(如果没有边连接)。
2. 遍历所有顶点k(作为中间顶点),再遍历所有顶点i和j,计算出通过顶点k的路径是否更短。如果dist[i][j] > dist[i][k] + dist[k][j],则更新dist[i][j]的值为dist[i][k] + dist[k][j]。
3. 重复步骤2,直到遍历完所有的顶点k。

通过该算法计算得到的dist数组,可以得到任意两个顶点之间的最短路径长度。如果需要,还可以通过追溯dist数组,找到具体的最短路径。

Floyd-Warshall算法的时间复杂度为O(V^3),其中V为顶点数。由于需要遍历三次顶点,因此算法的执行效率相对较低,适用于解决较小规模的图。另外,Floyd-Warshall算法适用于解决带负权边的图中的最短路径问题。

Bellman-Ford算法

Bellman-Ford算法是一种用于解决带权重的有向图中的单源最短路径问题的动态规划算法。它可以找到从给定源点到所有其他顶点的最短路径长度,包括负权边的情况。

算法的基本思想是:
1. 创建一个一维数组dist,用于存储源点到所有顶点的当前最短路径估计值。将dist数组初始化为无穷大,除了源点dist[source] = 0。
2. 通过对所有边进行松弛操作,即对每条边(u, v)进行检查,如果dist[u] + weight(u, v) < dist[v],则更新dist[v]的值为dist[u] + weight(u, v)。
3. 重复步骤2 |V|-1次,其中|V|为顶点数。这样可以保证在每一轮松弛操作后,dist数组中的值会不断逼近最短路径。
4. 检查是否存在负权环路。在第|V|轮松弛操作后,再次遍历所有边,如果存在边(u, v)且满足dist[u] + weight(u, v) < dist[v],则表示存在负权环路。

通过该算法计算得到的dist数组,可以得到从源点到其他顶点的最短路径长度。如果存在负权环路,则无法得到正确结果。Bellman-Ford算法的时间复杂度为O(V*E),其中V为顶点数,E为边数。该算法的执行效率较低,适用于解决较小规模的图或带负权边的情况。

SPFA算法

题外话

这是NOIP2018年T1出题人写的。

引入正题

SPFA(Shortest Path Faster Algorithm)是一种用于解决有向图中单源最短路径问题的算法。它基于Bellman-Ford算法,但通过使用队列的方式来优化运行时间,使得在一般情况下具有较好的性能。

算法的基本思想是:
1. 创建一个一维数组dist,用于存储源点到所有顶点的当前最短路径估计值。将dist数组初始化为无穷大,除了源点dist[source] = 0。
2. 创建一个队列queue,用于存储待处理的顶点。
3. 将源点加入队列。
4. 当队列不为空时,从队列中取出一个顶点u,并遍历所有与u相邻的顶点v。
5. 如果通过顶点u可以获得一个更短的路径,则更新顶点v的dist值,并将顶点v加入队列,表示下一轮需要重新计算与v相邻的顶点的最短路径。
6. 重复步骤4和步骤5,直到队列为空。
7. 最终得到dist数组,其中dist[i]表示源点到顶点i的最短路径长度。

SPFA算法的基本思想与Bellman-Ford算法相似,但通过使用队列来避免了对所有顶点的多次松弛操作,从而提高了算法的效率。然而,由于SPFA算法的性能与图的具体结构有关,因此在某些情况下可能会表现出比较差的性能,例如存在负权环路的情况。在一般情况下,SPFA算法的时间复杂度为O(kE),其中k是一个常数(通常情况下k < 2),E为边数。

总结

总的来说,图论是数学的一个分支,研究的是图的性质和图中的问题。图由顶点和边组成,可以用来表示各种关系和网络结构。

图论有以下几个重要的概念和问题:

1. 顶点(Vertex):图中的一个节点,表示一个实体或一个概念。

2. 边(Edge):图中的连接顶点的线段,表示顶点之间的关系。

3. 有向图(Directed Graph):边有方向的图,表示顶点之间的有向关系。

4. 无向图(Undirected Graph):边没有方向的图,表示顶点之间的无向关系。

5. 加权图(Weighted Graph):边上带有权值的图,表示顶点之间的带权关系。

6. 最短路径问题(Shortest Path Problem):在图中找到两个顶点之间的最短路径,可以使用Dijkstra算法、Bellman-Ford算法、Floyd-Warshall算法等解决。

7. 最小生成树问题(Minimum Spanning Tree Problem):在图中找到一个包含所有顶点的子图,并且使用最少的边连接它们,可以使用Prim算法、Kruskal算法等解决。

8. 拓扑排序(Topological Sorting):有向无环图中,将顶点线性排序,使得所有的有向边从前面的顶点指向后面的顶点。

9. 图的遍历(Graph Traversal):访问图中的所有顶点,可以使用深度优先搜索(DFS)和广度优先搜索(BFS)等算法。

总之,图论是一门非常有用的数学工具,可以用来解决各种实际问题,如网络分析、路径规划、社交网络分析等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值