有边数限制的最短路

文章目录

    • 题目 有边数限制的最短路
    • 算法分析
      • 1、问题:为什么Dijkstra不能使用在含负权的图中?
      • dijkstra详细步骤
      • 2、什么是bellman - ford算法?
      • 3、bellman - ford算法的具体步骤
      • 4、在下面代码中,是否能到达n号点的判断中需要进行if(dist[n] > INF/2)判断,而并非是if(dist[n] == INF)判断,原因是INF是一个确定的值,并非真正的无穷大,会随着其他数值而受到影响,dist[n]大于某个与INF相同数量级的数即可
      • 5、bellman - ford算法擅长解决有边数限制的最短路问题
    • C ++ 代码
    • Java 代码

题目 有边数限制的最短路

给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数。

请你求出从 1 号点到 n号点的最多经过 k条边的最短距离,如果无法从 1号点走到 n号点,输出 impossible

注意:图中可能 存在负权回路

输入格式
第一行包含三个整数 n,m,k。

接下来 m行,每行包含三个整数 x,y,z,表示存在一条从点 x到点 y的有向边,边长为 z。

点的编号为 1∼n。

输出格式
输出一个整数,表示从 1号点到 n号点的最多经过 k条边的最短距离。

如果不存在满足条件的路径,则输出 impossible

数据范围
1 ≤ n,k ≤ 500,
1 ≤ m ≤ 10000,
1 ≤ x,y ≤ n,
任意边长的绝对值不超过 10000。

输入样例
3 3 1
1 2 1
2 3 1
1 3 3
输出样例
3

算法分析

1、问题:为什么Dijkstra不能使用在含负权的图中?

(这是以前错误的分析,若看完这个例子分析觉得正确的说明对最短路理解得还不够透彻,这里不做删除)

分析:如图所示:
若通过Dijkstra算法可以求出从1号点到达4号点所需的步数为3 (每次选择离源点最短距离的点更新其他点)
但实际上从 1 号点到达 4 号点所需步数为 1 (1 –> 2 –> 3),因此不能使用 Dijkstra 解决含负权图的问题
在这里插入图片描述

正确的分析
Dijkstra算法的3个步骤

  1. 找到当前未标识的且离源点最近的点t
  2. t号点点进行标识
  3. t号点更新其他点的距离
    反例
    在这里插入图片描述

结果

dijkstra算法在图中走出来的最短路径是1 -> 2 -> 4 -> 5,算出 1 号点到 5 号点的最短距离是2 + 2 + 1 = 5,然而还存在一条路径是1 -> 3 -> 4 -> 5,该路径的长度是5 + (-2) + 1 = 4,因此 dijkstra 算法失效

dijkstra详细步骤

  1. 初始dist[1] = 0
  2. 找到了未标识且离源点1最近的结点1,标记1号点,用1号点更新其他所有点的距离,2号点被更新成dist[2] = 23号点被更新成dist[3] = 5
  3. 找到了未标识且离源点1最近的结点2,标识2号点,用2号点更新其他所有点的距离,4号点被更新成dist[4] = 4
  4. 找到了未标识且离源点1最近的结点4,标识4号点,用4号点更新其他所有点的距离,5号点被更新成dist[5] = 5
  5. 找到了未标识且离源点1最近的结点3,标识3号点,用3号点更新其他所有点的距离,4号点被更新成dist[4] = 3
  6. 结束
  7. 得到1号点到5号点的最短距离是5,对应的路径是1 -> 2 -> 4 -> 5并不是真正的最短距离

2、什么是bellman - ford算法?

Bellman - ford 算法是求含负权图的单源最短路径的一种算法,效率较低,代码难度较小。其原理为连续进行松弛,在每次松弛时把每条边都更新一下,若在 n-1 次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。
(通俗的来讲就是:假设 1 号点到 n 号点是可达的,每一个点同时向指向的方向出发,更新相邻的点的最短距离,通过循环 n-1 次操作,若图中不存在负环,则 1 号点一定会到达 n 号点,若图中存在负环,则在 n-1 次松弛后一定还会更新)

3、bellman - ford算法的具体步骤

for n次for 所有边 a,b,w (松弛操作)dist[b] = min(dist[b],back[a] + w)

注意:back[] 数组是上一次迭代后 dist[] 数组的备份,由于是每个点同时向外出发,因此需要对 dist[] 数组进行备份,若不进行备份会因此发生串联效应,影响到下一个点

4、在下面代码中,是否能到达n号点的判断中需要进行if(dist[n] > INF/2)判断,而并非是if(dist[n] == INF)判断,原因是INF是一个确定的值,并非真正的无穷大,会随着其他数值而受到影响,dist[n]大于某个与INF相同数量级的数即可

5、bellman - ford算法擅长解决有边数限制的最短路问题

时间复杂度 O(nm)
其中n为点数,m为边数

C ++ 代码

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 510, M = 10010;struct Edge
{int a, b, c;
}edges[M];int n, m, k;
int dist[N];
int last[N];void bellman_ford()
{memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < k; i ++ ){memcpy(last, dist, sizeof dist);for (int j = 0; j < m; j ++ ){auto e = edges[j];dist[e.b] = min(dist[e.b], last[e.a] + e.c);}}
}int main()
{scanf("%d%d%d", &n, &m, &k);for (int i = 0; i < m; i ++ ){int a, b, c;scanf("%d%d%d", &a, &b, &c);edges[i] = {a, b, c};}bellman_ford();if (dist[n] > 0x3f3f3f3f / 2) puts("impossible");else printf("%d\n", dist[n]);return 0;
}

Java 代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;public class Main {static int N = 510;static int M = 100010;static int n;//总点数static int m;//总边数static int k;//最多经过k条边static int[] dist = new int[N];//从1到点到n号点的距离static Node[] list = new Node[M];//结构体static int INF = 0x3f3f3f3f;static int[] back = new int[N];//备份dist数组public static void bellman_ford(){Arrays.fill(dist, INF);dist[1] = 0;for(int i = 0;i < k;i++){back = Arrays.copyOf(dist, n + 1);//由于是从1开始存到nfor(int j = 0;j < m;j++){Node node = list[j];int a = node.a;int b = node.b;int c = node.c;dist[b] = Math.min(dist[b], back[a] + c);}}if(dist[n] > INF/2) System.out.println("impossible");else System.out.println(dist[n]);}public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String[] str1 = reader.readLine().split(" ");n = Integer.parseInt(str1[0]);m = Integer.parseInt(str1[1]);k = Integer.parseInt(str1[2]);for(int i = 0;i < m;i++){String[] str2 = reader.readLine().split(" ");int a = Integer.parseInt(str2[0]);int b = Integer.parseInt(str2[1]);int c = Integer.parseInt(str2[2]);list[i] = new Node(a,b,c);}bellman_ford();}}
class Node
{int a, b, c;public Node(int a,int b,int c){this.a = a;this.b = b;this.c = c;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/11164.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

水准网间接平差

目录 一、原理概述二、案例分析三、代码实现 一、原理概述 间接平差的函数模型和随机模型为&#xff1a; L ^ B X ^ d D σ 0 2 Q σ 0 2 P − 1 \hat{L}B\hat{X}d\\ D\sigma_0^2Q\sigma_0^2P^{-1} L^BX^dDσ02​Qσ02​P−1 误差方程为&#xff1a; V B x ^ − l VB\ha…

信息系统项目管理师0104:详细可行性研究(7项目立项管理—7.2项目可行性研究—7.2.3详细可行性研究)

点击查看专栏目录 文章目录 7.2.3详细可行性研究1.详细可行性研究的依据2.详细可行性研究的原则3.详细可行性研究的方法4.详细可行性研究的内容5.详细可行性研究报告记忆要点总结7.2.3详细可行性研究 详细可行性研究是在项目决策前对与项目有关的技术、经济、

智慧公厕:打造智能、安全、舒适的公共厕所新时代

随着智慧城市建设的不断推进&#xff0c;公共设施的智能化也已成为一种必然趋势。在这一背景下&#xff0c;智慧公厕作为城市管理的一个重要方面&#xff0c;正逐渐走进人们的视野。通过对所在辖区内所有公共厕所的全域感知、全网协同、全业务融合以及全场景智慧的赋能&#xf…

如何训练一个大模型:LoRA篇

目录 写在前面 一、LoRA算法原理 1.设计思想 2.具体实现 二、peft库 三、完整的训练代码 四、总结 写在前面 现在有很多开源的大模型&#xff0c;他们一般都是通用的&#xff0c;这就意味着这些开源大模型在特定任务上可能力不从心。为了适应我们的下游任务&#xff0c;…

【退役之重学 Java】初步认识 AQS

一、AQS 是什么 Abstract Queued Synchronizer &#xff0c;翻译过来就是“抽象的排好队的同步器”。 AQS 是一个用来构建锁和同步器的框架。是用来构建锁或者其他同步器组件的重量级基础框架及整个JUC体系的基石&#xff0c;通过内置的FIFO队列来完成线程获取资源的排队工作&…

251 基于matlab的动态粒子群算法

基于matlab的动态粒子群算法。普通粒子群算法无法感知外界环境的变化&#xff0c;在外界环境发生改变时无法实时进行响应&#xff0c;因而缺乏动态环境寻优能力。在普通粒子群算法基本上通过增加敏感粒子得到一种动态粒子群算法&#xff0c;该算法通过实时计算敏感粒子的适应度…

2024年第七届可再生能源与电力工程国际会议(REPE 2024)即将召开!

2024年第七届可再生能源与电力工程国际会议&#xff08;REPE 2024&#xff09;将于2024年9月25-27日在中国北京召开, 由清华大学主办。REPE 2024将汇聚国内外知名专家学者通过主旨报告、分组讨论和互动交流等形式&#xff0c;分享最新的研究成果、技术进展和应用案例&#xff0…

【教程向】从零开始创建浏览器插件(二)深入理解 Chrome 扩展的 manifest.json 配置文件

第二步&#xff1a;深入理解 Chrome 扩展的 manifest.json 配置文件 上一次我们已经着手完成了一个自己的浏览器插件&#xff0c;链接在这里&#xff1a;我是链接 在本篇博客中&#xff0c;我们将更详细地探讨 Chrome 扩展中的 manifest.json 文件。这个文件是每个浏览器扩展…

docker容器实现https访问

前言&#xff1a; 【云原生】docker容器实现https访问_docker ssl访问-CSDN博客 一术语介绍 ①key 私钥 明文--自己生成&#xff08;genrsa &#xff09; ②csr 公钥 由私钥生成 ③crt 证书 公钥 签名&#xff08;自签名或者由CA签名&#xff09; ④证书&#xf…

C入门笔记

1. c文件执行过程 C语言程序的执行过程可以分为四个基本步骤&#xff1a;预处理、编译、汇编和链接。下面是这些步骤的简要概述&#xff1a; 预处理&#xff1a;在这个步骤中&#xff0c;预处理器将源代码中以 # 开头的指令进行处理&#xff0c;例如 #include 和 #define。预…

STM32快速入门(定时器之输出PWM波形)

STM32快速入门&#xff08;定时器之输出PWM波形&#xff09; 前言 本节主要讲解STM32利用通用定时器&#xff0c;利用CCR和CNT寄存器&#xff0c;输出指定占空比和频率的PWM波形。其功能的应用有&#xff1a;实现LED呼吸灯的效果、控制步进电机、控制直流电机转速等。 导航 …

ue5地编模块学习记录

ue5网站功能3d溜溜网下载模型https://anyconv.com/max-to-fbx-converter/3dmax转换fbx模型解决问题记录 一、光源 搜索光源搜索不到的时候可以点击 窗口> 对场景内的光照进行处理

最佳解决Maven同一依赖多版本共存问题,重复依赖(同一个jar包,多个版本)-maven-shade-plugin

先看链接:原文链接 参照原文链接生成的文件(下面是我放的位置) mvn指令 mvn install:install-file -DfileD:\mavenrepository/maven-shade.jar -DgroupIdcom.wj -DartifactIdmaven-shade -Dversion1.1 -Dpackagingjar如果配置了maven_home 和java_home可以任意打开cmd执行(…

Google: 在新知识上微调大语言模型是否会鼓励产生幻觉?

摘要 当大型语言模型通过监督式微调进行对齐时,它们可能会遇到在预训练期间没有获得的新事实信息。人们经常推测,这可能会教导模型产生事实上不正确的回应的行为,因为模型被训练成生成没有基于其预先存在的知识的事实。在这项工作中,Google研究了这种暴露在新知识下对微调后模…

基于springboot实现高校教师电子名片系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现高校教师电子名片系统演示 摘要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;名片信息因为其管理内容繁杂&#xff…

C++的数据结构(五):树和存储结构及示例

在计算机科学中&#xff0c;树是一种抽象数据类型&#xff08;ADT&#xff09;或是实现这种抽象数据类型的数据结构&#xff0c;用来模拟具有树状结构性质的数据集合。这种数据结构以一系列连接的节点来形成树形结构。在C中&#xff0c;树的概念和存储结构是实现各种复杂算法和…

Java--初识类和对象

前言 本篇讲解Java类和对象的入门版本。 学习目的&#xff1a; 1.理解什么是类和对象。 2.引入面向对象程序设计的概念 3.学会如何定义类和创建对象。 4.理解this引用。 5.了解构造方法的概念并学会使用 考虑到篇幅过长问题&#xff0c;作者决定分多次发布。 面向对象的引入 J…

GIAT: 蛋白质结构预测的新利器

瑞典Karolinska研究院在瑞典政府赞助下由Ben Murrell等研究团队在AlphaFold 3最新报告后提出这篇论文提出了一种非常有趣和创新的方法来生成蛋白质骨架结构,称为生成式不变角度转换器(GIAT)。与现有的主要基于扩散模型和流匹配的方法不同,GIAT采用了类似于大型语言模型(如GPT)中…

【C语言|数据结构】双向链表

文章目录 前言1、初步认识双向链表1.1 定义&#xff1a;1.2 结构1.3 节点的存储 2、双向链表的接口函数2.1 链表的节点的动态申请2.2 链表的初始化2.3 尾插2.4 头插2.5 头删2.5 尾删2.6 在pos节点后面添加数据2.6 删除pos节点 3、双向链表的实现&#xff1a; 前言 各位小伙伴大…

C控制语句:分支和跳转

1.1if语句 //colddays.c --找出0摄氏度以下的天数占总天数的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…