有邊數限制的最短路

文章目錄

    • 題目 有邊數限制的最短路
    • 算法分析
      • 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.pswp.cn/web/11164.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11164.shtml
英文地址,請注明出處:http://en.pswp.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;…

使用Python構建一個簡單的圖書管理系統

Python是一種強大而靈活的編程語言&#xff0c;它可以用于構建各種類型的應用程序&#xff0c;包括圖書管理系統。在這篇文章中&#xff0c;我們將學習如何使用Python和一些常見的庫來創建一個簡單的圖書管理系統。 1. 設計數據庫模型 首先&#xff0c;我們需要設計數據庫模型…

【退役之重學 Java】初步認識 AQS

一、AQS 是什么 Abstract Queued Synchronizer &#xff0c;翻譯過來就是“抽象的排好隊的同步器”。 AQS 是一個用來構建鎖和同步器的框架。是用來構建鎖或者其他同步器組件的重量級基礎框架及整個JUC體系的基石&#xff0c;通過內置的FIFO隊列來完成線程獲取資源的排隊工作&…

centos7時間同步教程

針對問題&#xff1a;在我們使用虛擬機配置好centos7后&#xff0c;發現服務器時間和當前時間對不上 通過命令查看時間不同步 date 或者 date -R修改/etc/sysconfig/clock文件如下內容&#xff0c;保存 vi /etc/sysconfig/clockZONE“Asia/Shanghai” UTCtrue ARCfalse重寫/e…

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。預…

一般社保測試

SI 分析和 PI 分析主要有以下區別&#xff1a; SI 分析&#xff1a; 主要關注信號在傳輸過程中的質量&#xff0c;如信號的失真、反射、串擾等問題。 側重于確保信號的準確傳輸和接收&#xff0c;以實現可靠的數字或模擬信號通信。 PI 分析&#xff1a; 著重于電源分配網絡…

STM32快速入門(定時器之輸出PWM波形)

STM32快速入門&#xff08;定時器之輸出PWM波形&#xff09; 前言 本節主要講解STM32利用通用定時器&#xff0c;利用CCR和CNT寄存器&#xff0c;輸出指定占空比和頻率的PWM波形。其功能的應用有&#xff1a;實現LED呼吸燈的效果、控制步進電機、控制直流電機轉速等。 導航 …

Java 類加載過程

什么是類加載 Java 類加載是指將 Java 字節碼文件加載到 Java 虛擬機&#xff08;JVM&#xff09;中&#xff0c;并將其轉化為可以執行的可執行代碼的過程。當 Java 程序在運行時引用某個類時&#xff0c;JVM 會首先檢查是否已經加載該類&#xff0c;如果沒有加載&#xff0c;則…

ue5地編模塊學習記錄

ue5網站功能3d溜溜網下載模型https://anyconv.com/max-to-fbx-converter/3dmax轉換fbx模型解決問題記錄 一、光源 搜索光源搜索不到的時候可以點擊 窗口> 對場景內的光照進行處理

【Java】數組訓練案例

訓練案例1 需求描述&#xff1a; 定義一個含有五個元素的數組&#xff0c;并為每個元素賦值&#xff0c;求數組中所有元素的最小值。 操作步驟描述&#xff1a; 1&#xff09; 定義5個元素數組。 2&#xff09; 可以使用初始化數組的兩種方式之一為數組元素賦值。 3&#xff09…

最佳解決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…