-
问题定义:求1号点到所有点的最短路径
-
时间复杂度:平均Om 最差On*m 适合稀疏图(邻接表建图方式 前面文章有提到)
-
算法思想
- 把1号点加入队列(数组模拟队列,前面有提)。
- 不断的取点,不断的循环所有边,不断的更新最短距离(故禁止负环出现)。 很像堆dij
- 退出条件是等所有的最短距离都无法更新的时候,队列为空。(队列只是个更新容器)
-
队列里面方的是:距离1号点距离变小的点
-
代码:
static int spfa(){ Arrays.fill(dist,0x3f3f3f3f); dist[1] = 0; push(1); st[1] = true; //标记点已经在队列中。 while(hh<=tt){ int t = pop(); st[t] = false; //出队 可重新入队。 for(int i = h[t];i!=-1;i = NE[i]){ //选择所有的临1边 int j = E[i]; //这里是t通向的所有边。 if(dist[j]>dist[t]+w[i]){ dist[j] = dist[t]+w[i]; //有更小的不管有没有在队列里,在这里都要被更新。队列只是一个用来访问变动过的点的容器罢了。那个点变动过,那么就要更新那个点后面的距离而已。(允许负权的地方) if(st[j] == false) { //只是判断有没有在队列中。 push(j); //只存距离变小了的点。 st[j] = true; } } } } // if(dist[n]==0x3f3f3f3f) return -1; //不能-1 直接返回 //在外面判断是否为 INF 即可, -1 也可能是最短路 return dist[n]; } ``` -
输出最短路
我们定义一个path[]数组,path[i]表示源点s到i的最短路程中,结点i之前的结点的编号(父结点),我们在借助结点u对结点v更新的同时,标记下path[v]=u,记录的工作就完成了(记录的永远是最后一次更新)。 然后递归输出
SPFA最短路算法(稀疏图的更优选择)(允许负权)(邻接表)(简单)
最新推荐文章于 2025-03-29 18:49:21 发布
本文详细介绍了求解图中1号点到所有点最短路径的SPFA(Shortest Path Faster Algorithm)算法。该算法适用于稀疏图,平均时间复杂度为Om,最坏情况为On*m。通过队列模拟,不断更新节点的最短距离,并避免负权环的影响。在代码实现中,使用数组记录距离并维护一个队列,直到无法更新最短距离为止。同时,利用path[]数组记录最短路径。SPFA算法是Dijkstra算法的一种优化,尤其适用于存在负权重的情况。
798

被折叠的 条评论
为什么被折叠?



