当前位置: 首页 > backend >正文

C++基础算法10:Bellman_Ford

1、概念

Bellman-Ford(贝尔曼-福特)算法是一个用于单源最短路径问题的经典算法,能够处理带负权边的图,是图论中非常重要的算法之一。

2、实战例子

给定n个节点,m条边。可能存在重环,权重可能为负数。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 1e5 + 10;
int n, m, k, d[N], me[N];  // d存储源点到节点的最短路径;me暂存当前的路径数组
struct Edge {int a, b, w;
} in[N];bool bell_ford() {fill(d, d + N, 0x3f3f3f3f);  // 初始化为无穷大d[1] = 0;  // 源点到自身距离为 0for (int i = 0; i < k; ++i) {memcpy(me, d, sizeof(d));  // 备份当前的最短路径for (int j = 0; j < m; ++j) {int a = in[j].a, b = in[j].b, w = in[j].w;d[b] = min(d[b], me[a] + w);  // 松弛操作}}return d[n] <= 0x3f3f3f3f / 2;  // 若目标节点距离大于无穷大,返回 false
}int main() {scanf("%d%d%d", &n, &m, &k);for (int i = 0; i < m; ++i) {scanf("%d%d%d", &in[i].a, &in[i].b, &in[i].w);}if (bell_ford()) cout << d[n];  // 输出最短路径else puts("impossible");  // 输出不可达return 0;
}

使用 me[] 是为了避免在一轮松弛中读取到“被修改后的值”,保证每次松弛都严格依赖上一次完整的结果,从而保证 Bellman-Ford 算法的正确性。

3、Dijkstra为什么解决不了负数权重的问题?

在Dijkstra算法中,每次都会选择一个当前最短的未处理节点,并且假设这个节点到达其他节点的路径不会再变得更短。该算法认为,当某个节点的最短路径确定后,后续不会有更短的路径通过该节点。这在所有边权都为非负数时是正确的,因为你只会逐步增加路径的长度,但不会出现路径长度突然减少的情况。

http://www.xdnf.cn/news/4129.html

相关文章:

  • 【交易】量价
  • 【C++】什么是头文件?
  • 论文报错4
  • 如何设计一个为QStackWidget的界面切换动画?
  • DNS解析过程
  • Ansible自动化运维工具
  • 可视化大屏开发全攻略:技术与实践指南
  • Wannier90文件与参数
  • 路由协议(静态路由、RIP、OSPF、BGP)
  • python读取图片自动旋转的问题解决
  • 深入理解 SSG:静态站点生成的原理、优势与实践
  • B4172 学习计划 题解
  • Redis常用命令表格汇总(超精炼)
  • 【2025牛客五一集训派对day4 C】题解
  • 【学习笔记】机器学习(Machine Learning) | 第五章(3)| 分类与逻辑回归
  • Linux网络编程 day4
  • 「OC」源码学习——objc_class的bits成员探究
  • 五一作业-day02
  • 软件设计师-错题笔记-程序语言
  • 《Effective java》 第三版 核心笔记
  • 蓝桥杯嵌入式按键长短按移植
  • LeetCode:链表的中间结点
  • Linux的时间同步
  • HTTP/HTTPS协议(请求响应模型、状态码)
  • 1247: 彩色的棋子(chess)
  • 《Spring 中 @Autowired 注解详解》
  • 2023年408真题及答案
  • 读《人生道路的选择》有感
  • Day11 训练
  • 30天开发操作系统 第27天 -- LDT与库