SPFA最短路算法(稀疏图的更优选择)(允许负权)(邻接表)(简单)

本文详细介绍了求解图中1号点到所有点最短路径的SPFA(Shortest Path Faster Algorithm)算法。该算法适用于稀疏图,平均时间复杂度为Om,最坏情况为On*m。通过队列模拟,不断更新节点的最短距离,并避免负权环的影响。在代码实现中,使用数组记录距离并维护一个队列,直到无法更新最短距离为止。同时,利用path[]数组记录最短路径。SPFA算法是Dijkstra算法的一种优化,尤其适用于存在负权重的情况。
  1. 问题定义:求1号点到所有点的最短路径

  2. 时间复杂度:平均Om 最差On*m 适合稀疏图(邻接表建图方式 前面文章有提到)

  3. 算法思想

    1. 把1号点加入队列(数组模拟队列,前面有提)。
    2. 不断的取点,不断的循环所有边,不断的更新最短距离(故禁止负环出现)。 很像堆dij
    3. 退出条件是等所有的最短距离都无法更新的时候,队列为空。(队列只是个更新容器)
  4. 队列里面方的是:距离1号点距离变小的点

  5. 代码:

      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];
      }
      ```
    
    
  6. 输出最短路

    我们定义一个path[]数组,path[i]表示源点s到i的最短路程中,结点i之前的结点的编号(父结点),我们在借助结点u对结点v更新的同时,标记下path[v]=u,记录的工作就完成了(记录的永远是最后一次更新)。 然后递归输出

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值