我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++图论之Bellman-Ford算法和SPFA算法的实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++图论之Bellman-Ford算法和SPFA算法的实现

给定一张有向图,若对于图中的某一条边(x,y,z),有dist[y]≤dist[x]+z成立,则称该边满足三角形不等式。如果所有边都满足三角形不等式,则dist数组就是所求的最短路。

Bellman-Ford算法

(x,y,z)表示的是一条从 x 出发, 到达 y ,长度为 z 的有向边。

首先介绍基于迭代的Bellman-Ford算法,它的流程如下:

1.扫描所有边(x,y,z),若dist[y]>dist[x]+z, 则用dist[x]+z更新dist[y]

2.重复上述操作,直到没有更新操作发生。

Bellman-Ford算法的时间复杂度是O(nm)

通过Bellman-Ford算法我们可以求解有边数限制的最短路问题。

例题:AcWing 853. 有边数限制的最短路

算法步骤

初始化 dist 数组为正无穷, dist[1] = 0

(外重循环)循环 i 从 1 到 n ,遍历 n 次表示:是不经过超过 i 条边到达终点的最短距离

(内重循环)循环 i 从 1 到 m, 遍历 m 条边,把所有的边都进行松弛操作:

每次取出两点以及以及连接他们的权重 (a,b,w)

用以下公式更新最短距离: dist[b]=min(dist[b],dist[a]+w)

注意点:

需要把dist数组进行一个备份,这样防止每次更新的时候出现串联

由于存在负权边,所以 return -1 的条件是dist[n]>0x3f3f3f/2

代码实现

#include <iostream>
#include <cstring>
using namespace std;
 
const int N = 510, M = 10010;
 
struct Edge
{
    int a, b, w;
}e[M]; // 存下每一条即可
int dist[N];
int back[N]; // 备份数组放置串联
int n, m, k;
 
void bellman_ford()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;
    
    for(int i = 0; i < k; i ++ ) // 不超过k条边
    {
        memcpy(back, dist, sizeof back);
        for(int j = 0; j < m; j ++ ) // 遍历所有边
        {
            int a = e[j].a, b = e[j].b, w = e[j].w;
            dist[b] = min(dist[b], back[a] + w);
        }
    }
}
 
int main()
{
    cin >> n >> m >> k;
    for(int i = 0; i < m; i ++ )
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        e[i] = {a, b, w};
    }
    
    bellman_ford();
    if(dist[n] > 0x3f3f3f3f / 2) puts("impossible");
    else cout << dist[n] << endl;
    
    return 0;
}

SPFA算法

SPFA算法在国际上通称为“队列优化的“Bellman-Ford算法”。

SPFA算法的流程如下:

1.建立一个队列,起初队列中只含有起点1

2.取出头结点 x ,扫描它的所有出边(x,y,z),若dist[y]>dist[x]+z,则使dist[y]用dist[x]+z来更新。同时若y不再队列中,则将y入队

在任意时刻,该算法的队列都保持了该拓展的节点。每次入队都相当于完成了一次 dist 数组的更新操作,使其满足三角不等式。一个节点可能会入队、出队多次。最终,图中所有的结点全部收敛到全部满足三角不等式的状态。

这个队列避免了对Bellman-Ford算法中不需要拓展的多余结点的冗余扫描,在随机图上的运行效率O(km)级别,其中 k 是一个很小的常数。

代码实现

SPFA求最短路

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
 
using namespace std;
 
const int N = 1e6 + 10;
 
int n, m;
int h[N], e[N], w[N], ne[N], idx;
int dist[N];
bool st[N];
 
void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}
 
void spfa()
{
    memset(dist, 0x3f, sizeof dist);
    queue<int> q;
    dist[1] = 0;
    st[1] = true;
    q.push(1);
    
    while(q.size())
    {
        int t = q.front();
        q.pop();
        
        st[t] = false;
        
        for(int i = h[t]; ~i; i = ne[i])
        {
            int j = e[i];
            if(dist[j] > dist[t] + w[i])
            {
                dist[j] = dist[t] + w[i];
                if(!st[j])
                {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
}
 
int main()
{
    scanf("%d%d", &n, &m);
 
    memset(h, -1, sizeof h);
    while (m -- )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }
 
    spfa();
    
    if(dist[n] == 0x3f3f3f3f) puts("impossible");
    else printf("%d",dist[n]);
 
    return 0;
}
 

以上就是C++图论之Bellman-Ford算法和SPFA算法的实现的详细内容,更多关于C++ Bellman-Ford SPFA算法的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++图论之Bellman-Ford算法和SPFA算法的实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#算法如何实现两数之和

小编给大家分享一下C#算法如何实现两数之和,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!题目给定一个整数数组 nums和一个目标值 target,请你在该数组中找
2023-06-26

用 PHP 实现图论算法的完整教程

本文介绍了使用 php 实现图论算法的步骤。算法包括广度优先搜索 (bfs)、深度优先搜索 (dfs) 和戴克斯特拉算法,可用于解决实际问题,例如社交网络分析和路径规划。用 PHP 实现图论算法的完整教程引言图论在计算机科学中扮演着至关
用 PHP 实现图论算法的完整教程
2024-05-07

C#图表算法之最短路径怎么实现

本篇内容主要讲解“C#图表算法之最短路径怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#图表算法之最短路径怎么实现”吧!从一个顶点到达另一个顶点的成本最小的路径。我们采用一个一般性的模
2023-06-30

Java算法之BFS,DFS,动态规划和贪心算法的实现

广度优先搜索(BFS)和深度优先搜索(DFS)是图遍历算法中最常见的两种算法,主要用于解决搜索和遍历问题。动态规划和贪心算法则用来解决优化问题。本文就来看看这些算法的具体实现吧
2023-05-14

C++图搜索算法之双端队列广搜怎么实现

这篇文章主要介绍“C++图搜索算法之双端队列广搜怎么实现”,在日常操作中,相信很多人在C++图搜索算法之双端队列广搜怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++图搜索算法之双端队列广搜怎么实现
2023-07-02

MD5算法原理及C#和JS实现的方法是什么

本篇内容主要讲解“MD5算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MD5算法原理及C#和JS实现的方法是什么”吧!一、简介MD5 是哈希算法(散列算法)的
2023-07-05

SHA-256算法原理及C#和JS实现的方法是什么

本篇内容主要讲解“SHA-256算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SHA-256算法原理及C#和JS实现的方法是什么”吧!一、简介SHA-256
2023-07-05

详解MD5算法的原理以及C#和JS的实现

MD5 是哈希算法(散列算法)的一种应用。这篇文章主要和大家介绍一下MD5算法的原理以及C#和JS的实现,文中的示例代码讲解详细,需要的可以参考一下
2023-03-19

DES&3DES算法原理及C#和JS实现的方法是什么

这篇文章主要介绍“DES&3DES算法原理及C#和JS实现的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“DES&3DES算法原理及C#和JS实现的方法是什么”文章能帮助大家解决问题。一、
2023-07-05

详解DES&3DES算法的原理以及C#和JS的实现

DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。3DES 算法通过对 DES 算法进行改进,增加 DES 的密钥长度来避免类似的攻击。本文就来聊聊它们的原理与实现吧
2023-03-19

C语言数据结构与算法之队列的实现详解

队列只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstInFirstOut)的原则。本文将通过实例详细说说队列的实现,需要的可以学习一下
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录