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

存在负权边的单源最短路径的原理和C++实现

负权图
 


此图用朴素迪氏或堆优化迪氏都会出错,floyd可以处理。

负环图


 
但floyd无法处理负权环,最短距离是无穷小。在环上不断循环。

经过k条边的最短距离(可能有负权变)

贝尔曼福特算法(bellman_ford)就是解决此问题的。

原理

循环k次,循环第i次时,m_vDis表示各点最多经过i-1条边的最短距离;vDis表示各点最多经过i条边的最短距离。

核心代码

template<const int INF=1000*1000*1000>
class CBellMan
{
public:
    CBellMan(int n, const vector<vector<int>>& edges,int s , int k )
    {
        m_vDis.assign(n, INF);
        m_vDis[s] = 0;
        for (int i = 1; i <= k; i++)
        {
            vector<int> curDis = m_vDis;
            for (const auto& v : edges)
            {
                if (INF == m_vDis[v[0]])
                {
                    continue;
                }
                curDis[v[1]] = min(curDis[v[1]], m_vDis[v[0]] + v[2]);
            }
            m_vDis.swap(curDis);
        }
    }
    vector<int> m_vDis;
};

测试样例

#include <vector>
#include<assert.h>
using namespace std;


int main()
{
    const int INF = 1000 * 1000 * 1000;
    vector<vector<int>> edges = { {0,1,1},{1,2,2},{2,3,3},{3,0,-7} };
    vector<vector<int>> results = { {0,INF,INF,INF},{0,1,INF,INF},{0,1,3,INF},{0,1,3,6},{-1,1,3,6},{-1,0,3,6},{-1,0,2,6},{-1,0,2,5},{-2,0,2,5} };
    for (int i = 0; i < results.size(); i++)
    {
        CBellMan<> bm(4, edges, 0, i);
        for (int j = 0; j < 4; j++)
        {
            assert(bm.m_vDis[j] == results[i][j]);
        }
    }
}


最短路径

最短路径就是经过“点数-1”条边的最短路径。如果没环,这些边可以到达任意点。如果有正权环和0权环,则拿掉这个环。如果负权环,则最小距离是无穷小。下面来检测负权环。循环“点数-1”后,再循环一次,如果有点的最短距离变小,则一定有负权环;没负权环,不会变短。如果有负权环,则再循环一次,一定有点(任意负权环的负权边的终点)距离变短。假定此点是e,拿掉负权环上所有的边后,源点到e的最短路径为Path。不拿掉负权环,则e的最短路径为:Path+此负权环。

核心代码

template<const int INF=1000*1000*1000>
class CBellMan
{
public:
    CBellMan(int n, const vector<vector<int>>& edges,int s , int k )
    {
        m_vDis.assign(n, INF);
        m_vDis[s] = 0;
        for (int i = 1; i <= k; i++)
        {
            vector<int> curDis = m_vDis;
            Do(edges, curDis);
            m_vDis.swap(curDis);
        }
    }
    bool Check(const vector<vector<int>>& edges)
    {
        vector<int> curDis = m_vDis;
        Do(edges, curDis);
        for (int i = 0; i < curDis.size(); i++)
        {
            if (m_vDis[i] != curDis[i])
            {
                return true;
            }
        }
        return false;
    }
    void Do(const std::vector<std::vector<int>>& edges, std::vector<int>& curDis)
    {
        for (const auto& v : edges)
        {
            if (INF == m_vDis[v[0]])
            {
                continue;
            }
            curDis[v[1]] = min(curDis[v[1]], m_vDis[v[0]] + v[2]);
        }
    }
    vector<int> m_vDis;
};


测试样例

#include <vector>
#include<assert.h>
#include "BellMan.h"
using namespace std;


void Test1()
{
    const int INF = 1000 * 1000 * 1000;
    vector<vector<int>> edges = { { 0,1,1 },{ 1,2,2 },{ 2,3,3 },{ 3,0,-7 } };
    vector<vector<int>> results = { { 0,INF,INF,INF },{ 0,1,INF,INF },{ 0,1,3,INF },{ 0,1,3,6 },{ -1,1,3,6 },{ -1,0,3,6 },{ -1,0,2,6 },{ -1,0,2,5 },{ -2,0,2,5 } };
    for (int i = 0; i < results.size(); i++)
    {
        CBellMan<> bm(4, edges, 0, i);
        for (int j = 0; j < 4; j++)
        {
            assert(bm.m_vDis[j] == results[i][j]);
        }
    }
}

void Test2()
{
    const int INF = 1000 * 1000 * 1000;
    vector<vector<int>> edges = { { 0,1,1 },{ 1,2,2 },{ 2,3,3 },{ 3,0,-7 } };
    vector<int> results = { false,false,true };
    for (int i = 0; i < 3; i++)
    {
        edges[3][2] = -5 - i;
        CBellMan<> bm(4, edges, 0, 3);
        assert(results[i] == bm.Check(edges));
    }
}
int main()
{
    Test1();
    Test2();
}
 


其它

测试环境

win7 VS2019 C++17

相关下载

源码及测试用例
https://download.csdn.net/download/he_zhidan/88393784
doc版文档,排版好
https://download.csdn.net/download/he_zhidan/88348653

相关文章:

存在负权边的单源最短路径的原理和C++实现

负权图 此图用朴素迪氏或堆优化迪氏都会出错&#xff0c;floyd可以处理。 负环图 但floyd无法处理负权环&#xff0c;最短距离是无穷小。在环上不断循环。 经过k条边的最短距离&#xff08;可能有负权变&#xff09; 贝尔曼福特算法(bellman_ford)就是解决此问题的。 原理 …...

15-自动化测试——理论知识

目录 1.什么是自动化测试&#xff1f; 2.常见的自动化测试分类 2.1.单元测试&#xff08;Java、Python&#xff09; 2.2.接口测试&#xff08;Java、Python&#xff09; 2.3.UI测试&#xff08;移动端、网站&#xff09; 3.如何实施自动化测试&#xff1f; 4.自动化测试…...

学信息系统项目管理师第4版系列17_干系人管理

1. 项目经理和团队管理干系人的能力决定着项目的成败 2. 干系人满意度应作为项目目标加以识别和管理 3. 发展趋势和新兴实践 3.1. 识别所有干系人&#xff0c;而非在限定范围内 3.2. 确保所有团队成员都涉及引导干系人参与的活 3.3. 定期审查干系人群体&#xff0c;可与单…...

专业PDF编辑阅读工具PDF Expert mac中文特点介绍

PDF Expert mac是一款专业的PDF编辑和阅读工具。它可以帮助用户在Mac、iPad和iPhone等设备上查看、注释、编辑、填写和签署PDF文档。 PDF Expert mac软件特点 PDF编辑&#xff1a;PDF Expert提供了丰富的PDF编辑功能&#xff0c;包括添加、删除、移动、旋转、缩放、裁剪等操作…...

处理机调度的概念,层次联系以及七状态模型

1.基本概念 当有一堆任务要处理&#xff0c;但由于资源有限&#xff0c;这些事情没法同时处理。 这就需要确定某种规则来决定处理这些任务的顺序&#xff0c;这就是“调度”研究的问题。 2. 三个层次 1.高级调度&#xff08;作业调度&#xff09; 高级调度&#xff08;作业…...

PS 图层剪贴蒙版使用方法

好 我们先打开PS软件 后面我们需要接触图框工具 在学习图框工具之前 先要掌握剪贴蒙版 这里 我们先点击左上角文件 然后选择新建 我们先新建一个画布出来 然后 我们点击 箭头指向处 新建一个空白图层 点击之后 会就多出一个空白图层 我们在这里 找到 矩形选框工具 然后 …...

总结1008

今日有些小摆烂&#xff0c;在家学习的日子&#xff0c;确实感觉不如在学校好&#xff0c;无论是在时间上&#xff0c;还是在效率上。在家复习效果因人而异吧&#xff0c;都到这个关键阶段了&#xff0c;可不能掉链子啊&#xff0c;明天势必要拿出100%的状态&#xff0c;心静不…...

软件工程从理论到实践客观题汇总(头歌第九章至第十七章)

九、软件体系结构设计 1、软件体系结构设计概述 2、软件体系结构模型的表示方法 3、软件体系结构设计过程 4、设计初步的软件体系结构 5、重用已有软件资源 6、精化软件体系结构 7、设计软件部署模型 8、文档化和评审软件体系结构设计 十、软件用户界面设计 1、用户界面设计概…...

ubuntu与win之间共享文件夹

ubuntu上设置共享文件夹 第一步&#xff1a;点击【设置】或【虚拟机弹窗下面的【设置】选项】 第二步&#xff1a;进入【虚拟机设置】页面&#xff0c;点击【选项】如下图所示 第三步&#xff1a;启用共享文件&#xff1a;点击【总是启用】第四步&#xff1a;添加共享文件&…...

flink处理函数--副输出功能

背景 在flink中&#xff0c;如果你想要访问记录的处理时间或者事件时间&#xff0c;注册定时器&#xff0c;或者是将记录输出到多个输出流中&#xff0c;你都需要处理函数的帮助&#xff0c;本文就来通过一个例子来讲解下副输出 副输出 本文还是基于streaming-with-flink这本…...

Java数据结构————队列

一 、队列 在Java中&#xff0c;Queue是个接口&#xff0c;底层是通过链表实现的。 只允许在一端进行插入数据操作&#xff0c; 在另一端进行删除数据操作的特殊线性表&#xff0c; 队列具有先进先出FIFO(First In First Out) 。 入队列&#xff1a; 进行插入操作的一端称为…...

办公网络构建

办公网络项目背景 XX州市益智软件科技有限公司是XX市第九职业技术学校校办企业&#xff0c;依托学校人力技术、场地资源&#xff0c;面向市场独立经营、服务社会&#xff0c;主要从事网络设备销售、网络综合布线与网络管理。该公司现租用实训基地二层作为公司的办公经营场地…...

单层神经网络

神经网络 人工神经网络&#xff08;Artificial Neural Network&#xff0c;ANN&#xff09;&#xff0c;简称神经网络&#xff08;Neural Network&#xff0c;NN&#xff09;&#xff0c;是一种模仿生物神经网络的结构和功能的数学模型或计算模型。1943年&#xff0c;McCulloc…...

htb-cozyhosting

HTB-CozyHosting https://app.hackthebox.com/machines/CozyHosting ──(kwkl㉿kwkl)-[~] └─$ tail -l /etc/hosts …...

网络安全渗透测试工具之skipfish

网络安全渗透测试工具skipfish介绍 在数字化的时代,Web 应用程序安全成为了首要任务。想象一下,您是一位勇敢的安全冒险家,迎接着那些隐藏在 Web 应用程序中的未知风险。而在这个冒险之旅中,您需要一款强大的工具来帮助您发现漏洞,揭示弱点。而这个工具就是 Skipfish。 …...

【Rust】文件系统

目录 一、读取文件的字符串行 二、避免读取写入同一文件 三、使用内存映射随机访问文件 四、过去 24 小时内修改过的文件名 五、查找给定路径的循环 六、递归查找重名文件 七、使用给定断言递归查找所有文件 八、跳过隐藏文件遍历目录 九、在给定深度的目录&#xff0…...

mysql双主双从读写分离

架构图&#xff1a; 详细内容参考&#xff1a; 结果展示&#xff1a; 178.119.30.16&#xff08;从&#xff09;- master 178.119.30.17&#xff08;从&#xff09;- slave 由上述结果可以看出&#xff0c;产生了主备节点同时抢占VIP的问题&#xff08;即脑裂问题&#xff09…...

postgresql-物化视图

postgresql-物化视图 物化视图创建物化视图刷新物化视图修改物化视图删除物化视图 物化视图 创建物化视图 postgresql使用create materialized view 语句创建视图 create materialized view if not exists name as query [with [NO] data];-- 创建一个包含员工统计信息的物化…...

多层神经网络和激活函数

多层神经网络的结构 多层神经网络就是由单层神经网络进行叠加之后得到的&#xff0c;所以就形成了层的概念&#xff0c;常见的多层神经网络有如下结构&#xff1a; 1&#xff09;输入层&#xff08;Input layer&#xff09;&#xff0c;众多神经元&#xff08;Neuron&#xff…...

Visual Studio Code键盘快捷键大全

Visual Studio Code键盘快捷键大全 前言导航快捷键编辑快捷键多光标快捷键终端快捷键调试快捷键文件管理快捷键Git快捷键代码格式化快捷键代码折叠快捷键工作区快捷键Markdown快捷键Zen模式快捷键窗口管理快捷键重构快捷键IntelliSense快捷键测试快捷键扩展快捷键 前言 欢迎来…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

goreplay

1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具&#xff0c;可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长&#xff0c;测试它所需的工作量也会呈指数级增长。GoRepl…...

2025-05-08-deepseek本地化部署

title: 2025-05-08-deepseek 本地化部署 tags: 深度学习 程序开发 2025-05-08-deepseek 本地化部署 参考博客 本地部署 DeepSeek&#xff1a;小白也能轻松搞定&#xff01; 如何给本地部署的 DeepSeek 投喂数据&#xff0c;让他更懂你 [实验目的]&#xff1a;理解系统架构与原…...

【AI News | 20250609】每日AI进展

AI Repos 1、OpenHands-Versa OpenHands-Versa 是一个通用型 AI 智能体&#xff0c;通过结合代码编辑与执行、网络搜索、多模态网络浏览和文件访问等通用工具&#xff0c;在软件工程、网络导航和工作流自动化等多个领域展现出卓越性能。它在 SWE-Bench Multimodal、GAIA 和 Th…...