当前位置: 首页 > 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快捷键测试快捷键扩展快捷键 前言 欢迎来…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)

UniApp 集成腾讯云 IM 富媒体消息全攻略&#xff08;地理位置/文件&#xff09; 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型&#xff0c;核心实现方式&#xff1a; 标准消息类型&#xff1a;直接使用 SDK 内置类型&#xff08;文件、图片等&#xff09;自…...