最短路
一、引入
给定两点之间有多条路径,且长度不一定都相等,让你求其最短的那条路径即为最短路问题。
解决最短路问题的算法有以下三种:
1. Dijkstra;
2. SPFA;
3. Floyd;
二、算法介绍
1、Dijkstra
u 从一个点出发,到达其他顶点的最短路径的长度。
u 基本操作:松弛
u d[u]+map[u, v]< d[v]这样的边(u,v)称为紧的(tense),可以对它进行松弛(relax): d[v] = d[u]+w
u 最开始给每一个点一个很大的d值,从d[s]=0开始,不断的对可以松弛的点进行松弛,不能松弛的时候已经求出了最短路了
2、SPFA
SPFA(Shortest Path Faster Algorithm)(队列优化)算法是求单源最短路径的一种算法,在Bellman-ford算法的基础上加上一个队列优化,减少了冗余的松弛操作,是一种高效的最短路算法。
设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,而且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
3、Floyd
用一个数组记录每一对顶点的距离,然后遍历每一个点,让其做中点,判断是否可以通过这个点让某对顶点的距离更小,如果可以则更新该对顶点的距离。
三、算法实现
1、Dijkstra
² Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止
² 注意该算法要求图中不存在负权边。
² 可以证明,具有最小的d[i](临时最短路)值的(还没加入最短路)点在此以后无法松弛
² 所以每次找最近的点进行松弛操作
1、在开始之前,认为所有的点都没有进行过计算,dis[]全部赋值为极大值(dis[]表示各点当前到源点的最短距离)
2、源点的dis值明显为0
3、还没算出最短路的点中dis[]最小的一个点u,其最短路就是当前的dis[u]
4、松弛操作:对于与u相连的所有点v,若dis[u]+cost[u][v]比当前的dis[v]小,更新dis[v]。
5、重复3,4直到源点到所有点的最短路都已求出
代码实现: