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

图论------贝尔曼-福德(Bellman-Ford)算法

算法概述:

        Bellman-Ford算法核心代码如下

        for(int i = 1;i<=n-1;i++)

                for(int j = 1;j<=m;j++)

                        if(dic[v[j]]> dic[u[j]] + w[j]]

                                dic[v[j]] = dic[u[j]] + w[j];

        首先我们要了解一个点就是我们这次不再使用邻接矩阵来存储图的信息,而是定义三个一维数组来存储图的信息。

        首先定义 u[n] 来存储边的起点,v[n]来存储边的终点,w[n]来存储边的长(权重)。

    例如存储如下元素

          4 4
        1 2 3
        2 4 7
        3 4 5
        3 1 3


        和Dijkstra算法一样,这段代码也是求单源最短路径,所以我们同样也要定义一个dic[n]数组来存储所有点到1的最短距离。注意,这里因为使用的并非邻接矩阵,所以初始化dic时默认除了dic[1] = 0以外,暂时全部看作不连通,也就是假设以以上数据为例,dic内容要初始化为

【0 ,inf, inf, inf】,其中inf看作无穷大,表示不通。

        那么我们再来看核心代码的最后两句。

        

                if(dic[v[j]]> dic[u[j]] + w[j]]

                                dic[v[j]] = dic[u[j]] + w[j];

        dic[v[j]]的值是1 到 v[j]这个点的值, dic[u[j]] 是 1 到 u[j] 这个点的值 , w[j] 是 u[j] 到 v[j] 的值,意思是如果如果 1 通过 1 -> u[j] -> v[j] 这条路比 1 -> v[j] 值小的话,更新dic[v[j]]的值。也就是通过u[j] ->v[j] 这条边进行松弛来优化路径。

        初始化示意图如下:

        

       

for(int i = 1;i<=n-1;i++)

                for(int j = 1;j<=m;j++)

                        if(dic[v[j]]> dic[u[j]] + w[j]]

                                dic[v[j]] = dic[u[j]] + w[j];

当第一轮循环时:

当先通过 j = 1 通过第一条边进行优化时, if(dic[ 2 ] > dic[ 1 ] + 3],发现dic[2 ] 需优化,然后

重置 dic[2] = dic[1]+3 = 3。

当 j = 2 时 通过第二条边进行优化时, if(dic[ 4 ] > dic[ 2 ] + 7],发现dic[4] 可以优化,然后

重置 dic[ 4 ] = dic[ 2 ] + 7 = 3+7 = 10。

当 j = 3时,通过第三条边进行优化时,if(dic[ 4 ] > dic[ 3 ] + 5],发现dic[4]无法优化,因为

dic[ 4 ] = 10 < dic[ 3 ] + 5  =inf + 5。

当 j = 4 时 通过第四条边进行优化时, if(dic[ 1 ] > dic[ 3 ] + 3],发现dic[1]无法优化,因为

dic[ 1 ] = 0 < dic[ 3 ] + 3  =inf + 3。

最后经过一轮松弛后得到 dic = [0, 3, inf ,10];


        当 i= 2 进行第二轮松弛时,

        

当先通过 j = 1 通过第一条边进行优化时, if(dic[ 2 ] > dic[ 1 ] + 3],发现dic[2 ] 无需优化,因为 dic[2] = dic[1]+3 = 3。

当 j = 2 时 通过第二条边进行优化时, if(dic[ 4 ] > dic[ 2 ] + 7],发现dic[4] 无需优化

当 j = 3时,通过第三条边进行优化时,if(dic[ 4 ] > dic[ 3 ] + 5],发现dic[4]无需优化

当 j = 4 时 通过第四条边进行优化时, if(dic[ 1 ] > dic[ 3 ] + 3],发现dic[1]无需优化

这样我们就完成了这组数据,因为这是构建的有向图,所以1 才无法到达 3.

既然很清晰流程了 我再丢给大家一组数据:

5 7
1 2 8
1 3 1
1 4 2
3 4 2
2 4 3
3 5 3
4 5 3

        现在请找到一张草稿纸来试着执行刚才所讲的流程。

具体代码:

        

#include<stdio.h>
int main(void)
{
    int u[10], v[10], w[10];
    int n, m, inf = 99999999;
    int dic[10] = { 0 };

    scanf_s("%d%d", &n, &m);

    for (int i = 1; i <= m; i++)
        scanf_s("%d%d%d", &u[i], &v[i], &w[i]);
//存储边的信息

    for (int i = 2; i <= n; i++)
        dic[i] = inf;
//初始化1 的单源最短路径值。

//核心代码

    for (int i = 1; i <= n - 1; i++)
        for (int j = 1; j <= m; j++)
            if (dic[v[j]] > dic[u[j]] + w[j])
                dic[v[j]] = dic[u[j]] + w[j];

    for (int i = 1; i <= n; i++)
        printf("%d ", dic[i]);
//输出结果
}

注意事项:

        最外层代码循环n-1次的原因是,n 个顶点,1到任何顶点的最多经过n-1个顶点。每一轮松弛循环如果没有完成单源最短路径的最终结果,都至少会有一次松弛。

        细心的同学可能会发现我们刚才使用的数据:

   5 7
1 2 8
1 3 1
1 4 2
3 4 2
2 4 3
3 5 3
4 5 3

        是上一篇文章的内容,在上一篇中结果是:0 5 1 2 4 。

而在这里答案是:0 8 1 2 4。

        那么为什么会造成这种影响呢,因为我们使用的这段代码是处理有向图的,而在上一篇文章中是处理无向图的,那么有没有什么办法来改进这段代码使代码能够处理无向图呢?答案当然是可以的,而且十分简单。

        聪明的同学注意到数据

          4 4
        1 2 3
        2 4 7
        3 4 5
        3 1 3

        在第二轮就能发现没有优化证明已经得出结果,每必要进行n-1轮循环,那么大家思考下,怎么提前退出循环呢?

课后作业:

        改进这段代码使代码能够处理无向图。

        如何证明达到最优解提前退出循环。

        明天带来答案。

相关文章:

图论------贝尔曼-福德(Bellman-Ford)算法

算法概述&#xff1a; Bellman-Ford算法核心代码如下 for(int i 1;i<n-1;i) for(int j 1;j<m;j) if(dic[v[j]]> dic[u[j]] w[j]] dic[v[j]] dic[u[j]] w[j]; 首先我们要了解一个点就是我们这次不再使用邻接矩阵来存储图的信息&#xff0c;而是定义三个一维数组来…...

带你彻底搞懂useLayoutEffect的使用场景

开篇第一句: useLayoutEffect 可能会影响性能。尽可能使用 useEffect。 useLayoutEffect 是 useEffect 的一个版本&#xff0c;在浏览器重新绘制屏幕之前触发。 使用方法 useLayoutEffect(setup, dependencies?)调用 useLayoutEffect 在浏览器重新绘制屏幕之前进行布局测量&…...

大厂进阶之二:React高级用法HOC、Hooks对比、异步组件

本文分文三部分&#xff1a; HOC高阶组件 higher order componentHooks 16.8版本后新增的钩子API异步组件使用lazy和suspense两个api实现组件代码打包分割和异步加载 一、HOC高阶组件 1、定义 高阶组件不是组件而是函数&#xff0c;是react中用于复用组件逻辑的高级技巧&am…...

【扒代码】ope.py

文件目录&#xff1a; 引用方式 if not self.zero_shot: # 非零样本情况下&#xff0c;计算边界框的宽度和高度 box_hw torch.zeros(bboxes.size(0), bboxes.size(1), 2).to(bboxes.device) box_hw[:, :, 0] bboxes[:, :, 2] - bboxes[:, :, 0] # 宽度 box_hw[:, :, 1] bbox…...

【Rust光年纪】探索Rust终端编程:从跨平台操作到用户界面设计

构建跨平台终端应用的完美选择&#xff1a;Rust 库综述 前言 随着终端应用程序的发展&#xff0c;越来越多的开发者开始寻找跨平台的、易于使用的库来构建终端用户界面和执行终端操作。本文将介绍几个流行的 Rust 库&#xff0c;它们提供了丰富的功能和灵活的 API 来满足不同…...

67、ceph

一、ceph 1.1、ceph概念 ceph是一个开源的&#xff0c;用c语言写的分布式的存储系统。存储文件数据。 /dev/sdb fdisk /dev/sdb gdisk /dev/sdb lvm 逻辑卷 可以扩容 raid 磁盘阵列 高可用 基于物理意义上的单机的存储系统。 分布式有多台物理磁盘组成一个集群&…...

最大正方形[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 在一个由0和1组成的二维矩阵内&#xff0c;找到只包含1的最大正方形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [["1","0","1","0","0"],[&quo…...

JavaScript 浅谈观察者模式 前端设计模式

2、观察者模式 2.1、观察者模式 2.1.1、前言 定义一种一对多的依赖关系&#xff0c;当一个对象发生变化时&#xff0c;所有依赖于它的对象都会自动收到通知并更新。 两个角色&#xff1a; Subject&#xff08;主题/被观察者&#xff09; Observer&#xff08;观察者&…...

【自动驾驶】自定义消息格式的话题通信(C++版本)

目录 新建消息文件更改包xml文件中的依赖关系更改cmakelist文件中的配置执行时依赖改变cmakelist编译顺序发布者程序调用者程序新建launch文件程序测试 新建消息文件 在功能包目录下&#xff0c;新建msg文件夹&#xff0c;下面新建mymsg.msg文件&#xff0c;其内容为 string …...

提升前端性能的JavaScript技巧

1. 前端JavaScript性能问题 前端JavaScript的性能问题可以显著影响Web应用的用户体验和整体性能。以下是一些常见的前端JavaScript性能问题: 1.1. 频繁的DOM操作 问题描述:JavaScript经常需要与DOM(文档对象模型)交互来更新页面内容。然而,每次DOM操作都可能触发浏览器的…...

“服务之巅:Spring Cloud中SLA监控与管理的艺术“

标题&#xff1a;“服务之巅&#xff1a;Spring Cloud中SLA监控与管理的艺术” 在微服务架构中&#xff0c;服务调用的可靠性和性能是至关重要的。服务级别协议&#xff08;Service Level Agreement&#xff0c;简称SLA&#xff09;是衡量服务性能的关键指标&#xff0c;它定义…...

ChatGPT角色定位提问提示词和指令完整版

角色定位提问 在与ChatGPT的对话中&#xff0c;角色定位提问是一种有效的策略&#xff0c;通过为ChatGPT和自己设定特定的角色或身份&#xff0c;可以引导对话朝着更加具体、有针对性的方向发展。这种提问方式不仅有助于ChatGPT更好地理解问题的背景和需求&#xff0c;还能使回…...

docker之我不会的命令

docker命令之我不会的 保存镜像&#xff08;打包&#xff09; docker save 镜像名或镜像id -o 保存路径和镜像名字例子&#xff1a; docker save tomcat -o /home/my_tomcat.tar加载保存的镜像 docker load -i 镜像保存的位置例子 在/home/路径下 docker load -i my_tomca…...

Together规则引擎 金融解决方案

目录 1.金融法规和期望正在发生变化,快速跟踪您的金融数字化变革&#xff01;2.抵押贷款功能集&#xff08;MFS&#xff09;3.MFS 示例模型4.MFS 知识特点5.MFS特定功能 1.金融法规和期望正在发生变化,快速跟踪您的金融数字化变革&#xff01; ogether规则引擎使金融机构能够简…...

【PyQt5】PyQt5 主要类

1.经常使用的模块 Sr.No.模块描述1QtCore其他模块使用的核心非GUI类2QtGui图形用户界面组件3QtMultimedia低级多媒体编程的类4QtNetwork网络编程的类5QtOpenGLOpenGL支持类6QtScript用于评估Qt脚本的类7QtSql使用SQL进行数据库集成的类8QtSvg用于显示SVG文件内容的类9QtWebKit…...

渗透测试实战-HFS远程RCE漏洞利用

免责声明&#xff1a;文章来源于真实渗透测试&#xff0c;已获得授权&#xff0c;且关键信息已经打码处理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本…...

企业级管理系统模板 -- 若依

文章目录 前言一、若依模板运行效果二、若依模板下载地址 1、版本说明2、前端下载地址3、后端下载地址三、修改模板代码名称四、修改前端标题及logo总结 前言 在我们学习别人的项目时&#xff0c;总会遇到许多不同的管理系统&#xff0c;例如&#xff1a;学生管理系统&#xf…...

无人车搭载无人机技术详解

无人车搭载无人机技术&#xff0c;是近年来智能交通与无人机技术深度融合的产物&#xff0c;旨在通过集成两者的优势&#xff0c;实现更加灵活、高效的作业能力。该技术将无人机作为无人车的一个可移动、多功能的传感器平台或执行器&#xff0c;通过协同工作&#xff0c;扩展无…...

从“抠图”到“抠视频”,Meta上新AI工具SAM 2。

继2023年4月首次推出SAM&#xff0c;实现对图像的精准分割后&#xff0c;Meta于北京时间2024年7月30日推出了能够分割视频的新模型SAM 2&#xff08;Segment Anything Model 2&#xff09;。SAM 2将图像分割和视频分割功能整合到一个模型中。所谓“分割”&#xff0c;是指区别视…...

一篇讲清楚什么是密码加密和加盐算法 | 附Java代码实现

目录 前言&#xff1a; 一、密码加密 1. MD5介绍 2.彩虹表攻击 3.测试复杂密码是否能被攻破 二、加盐算法 1.对密码123456演示加盐算法 2.盐值的储存 3.密码加盐思想总结 三、Java代码实现 前言&#xff1a; 早些年&#xff0c;数据泄露屡见不鲜&#xff0c;每个班上总…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...