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

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

DiscuzX3.5发帖json api

参考文章&#xff1a;PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下&#xff0c;适配我自己的需求 有一个站点存在多个采集站&#xff0c;我想通过主站拿标题&#xff0c;采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...