Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环。这是因为最长的没有环路的路,也只不过是V个点E-1条边构成的,所以松弛E-1次一定能得到最短路。因此这个算法相比 Dijkstra 首先其是对边进行增广,其次它能检测出负环的存在(若负环存在,那么最短路是取不到的,因为可以一直绕着这个负环将最小路径值不断缩小),这个弥补了 Dijkstra 的不足,但是其算法跑的比较慢,因此为了追求速度往往采用其“队列优化版”==>SPFA,因此想要理解SPFA最好先看看Bellman-ford算法。

SPFA 算法适用于含有负权边的最短路求解,其复杂度并没有网上传的那么神乎在理想情况下有论文指出其复杂度为O(kE)且k是一个约小于2的常数,但是在一些稠密图下其算法性能还是会退化到和 Bellman-ford 一样的 O( VE ),所以在稠密图下建议使用 Dij + Heap 优化的版本,稀疏图下 SPFA 还是很给力的!在 Bellman-ford 中发现啊最外层的 N-1 次循环未免盲目、实际上被松弛过的点我们希望其去继续松弛其他点,这样我们用队列将被松弛过的点存起来以便下一次继续松弛其他点,具体原理和做法可以参考下面的链接,顺便一提,SPFA还有两个优化==> SLF 与 LLL,具体也不阐述了。本文主要给出模板!

算法原理 or 学习参考链接 : 点我 、点我啦 、 点嘛!

Bellman-ford模板

///POJ 2387为例
#include<bits/stdc++.h>
using namespace std;
;
const int INF  = 0x3f3f3f3f;
struct EdgeNode{ int from, to, w; };
EdgeNode Edge[maxn*maxn];
int Dis[maxn];
int N, M, cnt;

inline void init()
{
    ; i<=N; i++)
        Dis[i] = INF;
    cnt = ;
}

bool BellmanFord(int st)
{
    Dis[st] = ;
    ; i<N; i++){///N-1 次循环后肯定能找出最短路
        bool Changed = false;
        int to, from, weight;

        ; j<cnt; j++){
            to     = Edge[j].to,
            from   = Edge[j].from,
            weight = Edge[j].w;

            if(Dis[from]!=INF && Dis[to] > Dis[from] + weight){
                Changed = true;
                Dis[to] = Dis[from] + weight;
                ///pre[to] = j; //Record paths
            }
        }

        if(!Changed) return true;///如果没有边可以继续松弛了,说明算法结束且无负环
        if(i==N && Changed) return false;///有负环
    }
    return false; ///一般来说绝无可能执行到这一步
}

int main(void)
{
    while(~scanf("%d %d", &M, &N)){
        init();
        int from, to, weight;
        ; i<M; i++){
            scanf("%d %d %d", &from, &to, &weight);
            Edge[cnt].from = from;
            Edge[cnt].to   = to;
            Edge[cnt].w    = weight;
            cnt++;
            Edge[cnt].to   = from;
            Edge[cnt].from = to;
            Edge[cnt].w    = weight;
            cnt++;
        }
        BellmanFord();
        printf("%d\n", Dis[N]);
    }
    ;
}

SPFA模板( SLF 优化版 )

///POJ 2387为例
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <string.h>
using namespace std;

const int INF=0x3f3f3f3f;
;

struct EdgeNode{ int v, w, nxt; };
EdgeNode Edge[maxn*maxn];
bool vis[maxn];
int Head[maxn], Dis[maxn], cnt;
int N, M;
/// int PushCnt[maxn]; ///记录每一个节点的入队次数、方便判断负环

inline void init()
{
    ; i<=N; i++)
        ///PushCnt[i] = 0;
        Head[i] = -,
        Dis[i]  = INF,
        vis[i]  = false;
    cnt = ;
}

inline void AddEdge(int from, int to, int weight)
{
    Edge[cnt].w = weight;
    Edge[cnt].v = to;
    Edge[cnt].nxt = Head[from];
    Head[from] = cnt++;
}

void SPFA(int st)///若要判断负环、改为 bool
{
    deque<int> que;
    que.push_back(st);
    vis[st]=true;
    Dis[st]=;
    while (!que.empty())
    {
        int T=que.front(); que.pop_front();
        vis[T]=false;
        ; i=Edge[i].nxt)
        {
            int v=Edge[i].v;
            int w=Edge[i].w;
            if (Dis[v]>Dis[T]+w){
                Dis[v]=Dis[T]+w;
                ///p[v] = T;
                if (!vis[v]){
                    ///if(++PushCnt[v] > N) return false; //有负环
                    vis[v]=true;
                    if(!que.empty() && Dis[v] < Dis[que.front()]) que.push_front(v);
                    else que.push_back(v);
                    //que.push_back(v); ///无SLF优化是这样写的
                }
            }
        }
    }
    /// return true;
}

int main(void)
{
    while(~scanf("%d %d", &M, &N)){
        init();
        int from, to, weight;
        ; i<M; i++){
            scanf("%d %d %d", &from, &to, &weight);
            AddEdge(from, to, weight);
            AddEdge(to, from, weight);
        }
        SPFA();
        printf("%d\n", Dis[N]);
    }
    ;
}

Bellman-ford算法、SPFA算法求解最短路模板的更多相关文章

  1. UESTC - 1987 童心未泯的帆宝和乐爷 (第k短路 A*算法+SPFA算法 模板)

    传送门: http://www.qscoj.cn/#/problem/show/1987 童心未泯的帆宝和乐爷 Edit Time Limit: 10000 MS     Memory Limit: ...

  2. 六度分离(floyd算法,SPFA算法,最短路—Dijkstra算法)

    Time Limit : 5000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submission(s) ...

  3. (模板)hdoj2544(最短路--bellman-ford算法&&spfa算法)

    题目链接:https://vjudge.net/problem/HDU-2544 题意:给n个点,m条边,求点1到点n的最短路. 思路: 今天学了下bellman_ford,抄抄模板.dijkstra ...

  4. Bellman-Ford算法与SPFA算法详解

    PS:如果您只需要Bellman-Ford/SPFA/判负环模板,请到相应的模板部分 上一篇中简单讲解了用于多源最短路的Floyd算法.本篇要介绍的则是用与单源最短路的Bellman-Ford算法和它 ...

  5. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  6. [板子]SPFA算法+链式前向星实现最短路及负权最短路

    参考:https://blog.csdn.net/xunalove/article/details/70045815 有关SPFA的介绍就掠过了吧,不是很赞同一些博主说是国内某人最先提出来,Bellm ...

  7. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  8. 用scheme语言实现SPFA算法(单源最短路)

    最近自己陷入了很长时间的学习和思考之中,突然发现好久没有更新博文了,于是便想更新一篇. 这篇文章是我之前程序设计语言课作业中一段代码,用scheme语言实现单源最段路算法.当时的我,花了一整天时间,学 ...

  9. Bellman-Ford & SPFA 算法——求解单源点最短路径问题

    Bellman-Ford算法与另一个非常著名的Dijkstra算法一样,用于求解单源点最短路径问题.Bellman-ford算法除了可求解边权均非负的问题外,还可以解决存在负权边的问题(意义是什么,好 ...

随机推荐

  1. 吴恩达机器学习(二) 单变量线性回归(Linear Regression with one variable)

    一.模型表示 1.一些术语 如下图,房价预测.训练集给出了房屋面积和价格,下面介绍一些术语: x:输入变量或输入特征(input variable/features). y:输出变量或目标变量(out ...

  2. 应用安全 - 软件漏洞 - 可视化平台kibana漏洞汇总

    CVE-2019-7609  Date: 类型: RCE 前置条件: Timelion And Canvas 影响范围: kibana-RCE < PoC | ExP: https://gith ...

  3. 路由器桥接时,为什么要关闭 DHCP 服务器?

    问:看网上的一些教程,路由器设置无线桥接的时候,副路由器中的 DHCP 服务器需要关闭,请问这是为什么? 答:两个路由器无线桥接时,之所以要关闭副路由器的 DHCP 服务器,是为了避免 IP 地址错误 ...

  4. PostgreSQL设计之初的大量论文

    引自:https://www.docs4dev.com/docs/zh/postgre-sql/11.2/reference/biblio.html#STON86 该网站是一个PostgreSQL手册 ...

  5. [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)

    [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...

  6. Node.js连接RabbitMQ,断线重连,动态绑定routing key

    RabbitMQ官方提供的教程https://www.rabbitmq.com/tuto...,是基于回调的. 下面将给出基于Promise式的写法.并且实现动态的队列绑定 初始化配置 const a ...

  7. 卸载OpenIV

    最近把 GTA5 卸载了,于是也想把用来修改 MOD 的 OpenIV 也卸载了. 结果在设置中,进行卸载的时候,弹出这个窗口 解决方案 1.首先打开 文件所在位置 2.右键,选择 属性,打开文件所在 ...

  8. QRCode.js一个生成二维码的javascript库

    前言 最近在开发中遇到一个需求:将后端返回的链接转换成二维码,那么如何来实现呢?我们可以使用QRCode.js来解决这一问题 什么是 QRCode.js? QRCode.js 是一个用于生成二维码的 ...

  9. js验证小数或者整数

    利用正则表达式校验是否为小数或者整数,废话不多说直接上demo(此正则表达式无法校验负数和数字为00开头的数字). PS:(如果有不对之处,请批评指教) <!DOCTYPE html> & ...

  10. win10常用的dos命令

    1.calc:启动计算器 2.appwiz.cpl:程序和功能 3.certmgr.msc:证书管理实用程序 4.charmap:启动字符映射表 5.chkdsk.exe:Chkdsk磁盘检查(管理员 ...