图论最短路:Bellman-Ford与其优化SPFA算法的一点理解

本文深入探讨了Bellman-Ford算法,解释了其在有边数限制的最短路问题中的应用,以及如何通过k次迭代找到最短路径并检测负权环。松弛操作作为算法核心,每次成功更新都能发现新最短路。同时,对比了SPFA算法,它是Bellman-Ford的一种优化,通过队列维护被松弛的点以提高效率。
摘要由CSDN通过智能技术生成


前言

随着对图论的深入,内心产生了很多问题。
之前的文章:图论最短路及生成树(Prim,Djikstra,Spfa,Bellan-ford,kruskal,topsort)


一、对Bellman-Ford的深入理解

1. Bellman-Ford有什么用?

Bellman-Ford算法效率低于dijistra算法,但具有一定实际意义。可以解决有边数限制的最短路问题。
想象这样一个场景:你在一号城市,想去n号城市去旅游。但是飞机没有1号城市从直达n号城市的(只能换乘飞机到达)。你想要花费最少到达目的地;但是吧,每换乘一次,你的心情就会变差一回,也就是说最多换乘k次。问最优解是什么?

Bellman-ford算法:
可以用于判断是否存在负权回路
步骤:
       for  k次循环(最多经过k条边)
         for  所有边a,b,w(权重)
           更新:dist[b] = min(dist[b],dist[a]+w)    // 即松弛操作
负权环,指的是一个图中存在一个环,里面包含的边的边权总和<0  

2. 什么是松弛操作?

松弛操作:为一次成功的更新dist[x]操作
每一次成功的松弛操作,都意味着我们发现了一条新的最短路。

3. Bellman-Ford的k次迭代意义?

  1. Bellman-Ford:共迭代k次,每次迭代,对图中所有的点的dist进行一次松弛操作,即更新一次最短路
  2. k次迭代的实际意义:每次迭代k,我们找到了经历了k条边的最短路。

4. 一个重要定理

只有上一次迭代中松弛过的点才有可能参与下一次迭代的松弛操作。

5. 对于模板的深入理解

  1. 大致过程:
    设置一个起点令dist[起点] = 0,此时认为起点进行过一次松弛操作。每次通过上次进行过松弛操作的点去更新可能参与下一次松弛操作的点,这有点像BFS,一圈一圈计算,有边数限制的话则最多松弛k次。
int Bellman_ford(){
    memset(dist,0x3f,sizeof(dist));
    dist[1] = 0;
    
    for(int i=0;i<k;i++){
        memcpy(backup,dist,sizeof dist);
        
        for(int i=0;i<m;i++){
            int a = edges[i].a,b = edges[i].b,c = edges[i].w;
            
            dist[b] = min(dist[b],backup[a]+c);
        }
    }
    
    if(dist[n] > 0x3f3f3f3f/2) return -1;
    else return dist[n];
}
  1. k次迭代的意义? 见上
  2. 为什么要用backup数组?
    backup保存的前几次发生松弛操作的点,依据定理:这些发生过松弛的点可能参与下一次的松弛操作进而更新更多的点。每次进行一大次松弛操作的时候,不能动态更新,所以需要backup数组。因为松弛操作只能更新一圈的点,这样容易更新紊乱。

二、Bellman-Ford到SPFA

将Bellman-Ford中遍历每条边的做法改变为遍历那些被成功松弛的点的邻点,我们可以简单地通过一个队列来维护这些被成功松弛的点,这个小小的改进可以带来巨大加速,改进之后的算法被称为SPFA。


SPFA算法模板:见之前博客(上面链接)。

解决:1. 最短路。 2. 判断负环。

比较:SPFA与Dijkstra


三、 一点问题

为什么采用结点入队次数来判断负环比统计当前每个点的最短路中所包含的边数是否大于n的运行时间多?


文章部分参考:深入理解Bellman-Ford(SPFA)算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辽宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值