Bellman_Ford 及其队列优化(SPFA)

设计背景

    (B)
    Richard Bellman,1958,DP
    Lester Ford Jr. 
    美国数学家,
    网络流,
    (S)
    段凡丁,1994,西南交通大学
    Shortest Path Faster Algorithm
    Bellman-ford最早的论文中曾提到过使用队列进行优化

过程模拟

  • 设起点为s,

    dis[v]表示从s到v的最短路径,

    pre[v]为v的前驱节点,用来输出路径

    w[j]是边j的长度。

   1. 创建源顶点v到图中所有顶点的距离的集合dis,
       为图中的所有顶点指定一个距离值,
       初始均为Inf,源顶点距离为0;

   2. 计算最短路径,执行V-1次遍历;

   3. 对于图中的每条边:
        如果起点u的距离d加上边的权值w小于终点 v的距离d,
        则更新终点v的距离值d;

   4.检测图中是否有负权边形成了环,
        遍历图中的所有边,计算u至v的距离,
        如果对于v存在更小的距离,
        则说明存在环
   (无向图不能用这种方法判断负环)
  • 初始化:

     dis[v]=∞(v≠s);dis[s]=0; pre[s]=0;

 

     for(int i=1; i<=n-1; i++)
        for(int j=1; j<=E; j++)
            if(dis[u]+w[j]<dis[v]){
                dis[v]=dis[u]+w[j];
                pre[v]=u;
            }

 

(又到了有图有真相的时候了)

(B)

         0. dis[1]=0; dis[2,3,4,5]=INF

         1. dis[1]=0,dis[2]=2,dis[3]=4,dis[4]=7,dis[5]=4

         2. dis[1]=0,dis[2]=2,dis[3]=3,dis[4]=4,dis[5]=4

         3. ...

         4. last round.

(S)

        Q={1} d[1...5]={0, INF, INF, INF, INF}

        Q={2,3,4} d[1...5]={0, 2, 4, 7, INF}

        Q={3,4,5} d[1...5]={0, 2, 3, 7, 4}

        Q={4,5} d[1...5]={0, 2, 3, 4, 4}

        Q={5} d[1...5]={0, 2, 3, 4, 4}

        Q={} d[1...5]={0, 2, 3, 4, 4}

        END.

代码实现

(B)

(S)

  void bellmanFord(int x)
    {
        for(int i=1; i<=n; i++)
            dis[i]=(i==x) ? 0 : INF;
        memset(v, 0, sizeof(v)); //inq
        queue<int> q;
        q.push(x);
        v[x]=1;
        while(!q.empty())
        {
            int from=q.front();
            q.pop();
            v[from]=0;
            for(edge * p=h[p]; p; p=p->next)
            {
                int to=p->to;
                int w =p->w;
                if(dis[from]+w<dis[to])
                {
                    dis[to]=dis[from]+w;
                    if(!v[to]) q.push(to), v[to]=1;
                }
            }
        }
    }

 

使用二维pre数组记录路径


所以说了这么多好像大家都知道的东西emmm

那么

Bellman_Ford与SPFA的整体策略都是通过边而松弛,

不断减小dis[x]的值

Bellman_Ford的思想是沿着最长的路径链(n-1)步进行优化dis[x]的值,

其中的很多操作是徒劳无益的

qwq

相较而言

SPFA利用队列动态更新最小值

    它所做的优化:

    1. 从起点开始沿路径链开始BFS,

       避免无益的松弛操作

    2.本质是优化了边松弛的顺序

    3. 当dis[x]被松弛小了应重新从x起BFS

emmm

第二篇博客就这么先结束吧;

希望自己可以慢慢进阶;

在这条路上越走越远~

你们也是~

今でもあなたは私の光。

转载于:https://www.cnblogs.com/Emotion-Blog/p/10391616.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值