算法-圖-dijkstra 最短路徑

理論知識

dijkstra三部曲

樸素版dijkstra

模擬過程?

堆優化版dijksra

經典模版例題

Dijkstra求最短路 I ??

參加科學大會(第六期模擬筆試)--模版題

網絡延遲

ref


理論知識

????????最短路是圖論中的經典問題即:給出一個有向圖,一個起點,一個終點,問起點到終點的最短路徑。

????????dijkstra算法:在有權圖(權值非負數)中求從起點到其他節點的最短路徑算法。需要注意兩點:

  • dijkstra 算法可以同時求 起點到所有節點的最短路徑
  • 權值不能為負數

dijkstra三部曲

  1. 第一步,選源點到哪個節點且該節點未被訪問過;(minDist數組里的數值,結合visited數組篩選出未訪問的節點)
  2. 第二步,該最近節點被標記訪問過;(更新visited數組)
  3. 第三步,更新非訪問節點到源點的距離(即更新minDist數組)。minDist數組 用來記錄 每一個節點距離源點的最小距離。(更新minDist數組)(初始化的時候就應該初始為最大值

樸素版dijkstra

模擬過程?

????????①初始化:節點0 不做處理,統一從下標1 開始計算,源點(節點1) 到自己的距離為0,所以 minDist[1] = 0;?此時所有節點都沒有被訪問過,所以 visited數組都為0。

? ? ? ? ②dijkstra 三部曲 :

?? ??? ??

? ? ? ??

?? ? ?

? ??

?更新 minDist數組,即:源點(節點1) 到 節點6 、 節點3 和 節點4【與當前被訪問節點2相連的節點】的距離。

  • 源點到節點6的最短距離為5,小于原minDist[6]的數值max,更新minDist[6] = 5
  • 源點到節點3的最短距離為3,小于原minDist[3]的數值4,更新minDist[3] = 3
  • 源點到節點4的最短距離為6,小于原minDist[4]的數值max,更新minDist[4] = 6

?

  • 源點到節點4的最短距離為5,小于原minDist[4]的數值6,更新minDist[4] = 5

?

?

...........

...........最終

????????節點1)到終點(節點7)的最短距離就是 minDist[7] ,按上面舉例講解來說,minDist[7] = 12,節點1 到節點7的最短路徑為 12。?

堆優化版dijksra

? ? ? ? 1、鄰接表結構存儲:?vector<vector<pair<int, int>>> adj(n + 1); // 鄰接表直接存儲邊

? ? ? ? 2、初始化最? 短距離數組和優先隊列,設定起點距離

????????使用小頂堆(priority_queue)存儲?<距離, 節點>?對,初始時將起點?(0, 1)?加入隊列

????????????????priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

? ? ? ? 3、主循環:通過優先隊列快速找到當前最短路徑節點,并更新鄰接節點。

????????????????

用到的數據結構:

?vector<vector<pair<int, int>>> adj(n + 1)

adj[1] = { {2, 2}, {3, 4} }; // 從 1 出發,有 1→2 (權2),1→3 (權4)
adj[2] = { {3, 1}, {4, 7} }; // 從 2 出發,有 2→3 (權1),2→4 (權7)

priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;

動態維護當前擴展的最短路徑節點

經典模版例題

Dijkstra求最短路 I??

完整代碼:

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,m;cin>>n>>m;vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));for(int i=1;i<=m;i++){int x,y,z;cin>>x>>y>>z;if (z < grid[x][y]) {  // 處理重邊,保留最小權重grid[x][y] = z;}}vector<int> minDist(n+1,INT_MAX);vector<bool> visited(n+1,false);int start=1;minDist[start]=0;for(int i=1;i<=n;i++){int minval=INT_MAX;int cur=-1;for(int j=1;j<=n;j++){if(!visited[j]&&minDist[j]<minval){minval=minDist[j];cur=j;}}if (cur == -1) break;  // 所有剩余節點不可達visited[cur]=true;for(int j=1;j<=n;j++){if(!visited[j]&&grid[cur][j]!=INT_MAX&&grid[cur][j]+minDist[cur]<minDist[j]){minDist[j]=minDist[cur]+grid[cur][j];}}}if(minDist[n]==INT_MAX) cout<<"-1";else cout<<minDist[n];return 0;
}

注意重邊?????!!!!??

堆優化版:

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m;vector<vector<pair<int, int>>> adj(n + 1); // 鄰接表直接存儲邊// 讀取邊并構建鄰接表(無需預處理二維數組)for (int i = 0; i < m; ++i) {int x, y, z;cin >> x >> y >> z;adj[x].emplace_back(y, z); // 直接添加所有邊}// Dijkstra算法vector<int> dist(n + 1, INT_MAX);priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;dist[1] = 0;pq.push({0, 1});while (!pq.empty()) {auto [d, u] = pq.top();pq.pop();if (d > dist[u]) continue; // 跳過過時記錄for (auto [v, w] : adj[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.push({dist[v], v});}}}// 輸出結果cout << (dist[n] == INT_MAX ? -1 : dist[n]);return 0;
}

?

參加科學大會(第六期模擬筆試)--模版題

完整代碼:?(我真的好愛卡哥,代碼簡潔又易懂!!!!!)

#include<bits/stdc++.h>
using namespace std;
int main()
{int n,m;cin>>n>>m;//鄰接矩陣存儲vector<vector<int>> grid(n+1,vector<int>(n+1,INT_MAX));//初始化數值為INT_MAXfor(int i=0;i<m;i++) //輸入邊權{int s,e,v;cin>>s>>e>>v;grid[s][e]=v;//存儲邊權值}int start=1;//記錄源點,從哪個點開始走int end=n;//記錄終點vector<int> minDist(n+1,INT_MAX);//存儲每個點至源點的最小距離minDist[start]=0;//源點到自身距離為0;vector<bool> visited(n+1,false);//記錄該點是否被訪問過,初始化都沒有被訪問過//依次遍歷所有結點for(int i=1;i<=n;i++){int minval=INT_MAX;int cur=start;//記錄當前被訪問的點中哪個點距離源點最近//1、選距離源點最近&&沒有被訪問過的點for(int v=1;v<=n;v++){if(!visited[v]&&minDist[v]<minval){minval=minDist[v];cur=v;//記錄該最近結點的id}}//2、標記該最近結點beifnagwvisited[cur]=true;//3、更新其他非訪問節點到源點的距離(更新minDist數組)for(int v=1;v<=n;v++){//沒有被訪問過的、與 cur相連的、更新后minDist更小的if(!visited[v]&&grid[cur][v]!=INT_MAX &&minDist[v]>minDist[cur]+grid[cur][v])minDist[v]=minDist[cur]+grid[cur][v];}}//不能到達終點if(minDist[end]==INT_MAX) cout<<-1<<endl;else cout<<minDist[end]<<endl; //輸出到達終點的最短路徑return 0;}

堆優化版:

#include <bits/stdc++.h>
using namespace std;int main() {int n, m;cin >> n >> m;// 鄰接表存儲:adj[x]保存從x出發的所有邊,格式為<目標節點, 邊權>vector<vector<pair<int, int>>> adj(n + 1);// 處理輸入并保留最小邊權(處理重邊)vector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));for (int i = 0; i < m; ++i) {int s, e, v;cin >> s >> e >> v;if (v < grid[s][e]) grid[s][e] = v;  // 僅保留最小權重}// 將鄰接矩陣轉換為鄰接表for (int x = 1; x <= n; ++x) {for (int y = 1; y <= n; ++y) {if (grid[x][y] != INT_MAX) {adj[x].push_back({y, grid[x][y]});}}}// Dijkstra堆優化實現vector<int> dist(n + 1, INT_MAX);        // 存儲起點到各節點的最短距離priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; // 小頂堆,格式<距離, 節點>dist[1] = 0;                             // 起點距離初始化為0pq.push({0, 1});                         // 將起點加入堆while (!pq.empty()) {auto [d, u] = pq.top();              // 取出當前距離最小的節點pq.pop();if (d > dist[u]) continue;           // 跳過過時的路徑記錄for (auto [v, w] : adj[u]) {         // 遍歷所有鄰接節點if (dist[v] > dist[u] + w) {     // 發現更短路徑dist[v] = dist[u] + w;       // 更新距離pq.push({dist[v], v});       // 將新距離加入堆}}}// 輸出結果:終點不可達則輸出-1cout << (dist[n] == INT_MAX ? -1 : dist[n]) << endl;return 0;
}

?

網絡延遲

#include<bits/stdc++.h>
using namespace std;int main() {int n, k, m;cin >> n >> k >> m;vector<vector<int>> grid(n+1, vector<int>(n+1, INT_MAX));for(int i = 0; i < m; ++i) {int u, v, w;cin >> u >> v >> w;grid[u][v] = w; // 存儲有向邊}vector<int> minDist(n+1, INT_MAX);vector<bool> visited(n+1, false);minDist[k] = 0; // 起點距離為0for(int i = 1; i <= n; ++i) {int minVal = INT_MAX;int cur = -1;// 尋找當前未訪問的最小距離節點for(int v = 1; v <= n; ++v) {if (!visited[v] && minDist[v] < minVal) {minVal = minDist[v];cur = v;}}// 所有剩余節點不可達if (cur == -1) break;visited[cur] = true;// 更新相鄰節點for(int v = 1; v <= n; ++v) {if (!visited[v] && grid[cur][v] != INT_MAX && minDist[cur] != INT_MAX) {if (minDist[v] > minDist[cur] + grid[cur][v]) {minDist[v] = minDist[cur] + grid[cur][v];}}}}int maxTime = 0;for(int i = 1; i <= n; ++i) {if (minDist[i] == INT_MAX) {cout << -1 << endl;return 0;}maxTime = max(maxTime, minDist[i]);}cout << maxTime << endl;return 0;
}

堆優化版:?

#include <bits/stdc++.h>
using namespace std;int main() {int n, k, m;cin >> n >> k >> m;vector<vector<pair<int, int>>> adj(n + 1); // 鄰接表存儲圖for (int i = 0; i < m; ++i) {int u, v, w;cin >> u >> v >> w;adj[u].emplace_back(v, w);}// Dijkstra算法vector<int> dist(n + 1, INT_MAX);priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;dist[k] = 0;pq.push({0, k});while (!pq.empty()) {auto [d, u] = pq.top();pq.pop();if (d > dist[u]) continue;for (auto [v, w] : adj[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.push({dist[v], v});}}}int maxTime = *max_element(dist.begin() + 1, dist.end());cout << (maxTime == INT_MAX ? -1 : maxTime) << endl;return 0;
}

?

和模版幾乎一樣,只是最后判斷為:所有的minDist不是INT_MAX(均可達),輸出是最大的時間(所有舉例源點的最短路徑中最大的那一個!!!!!!) 好開心~?

ref

代碼隨想錄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72594.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72594.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72594.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Qt添加MySql數據庫驅動

文章目錄 一. 安裝MySql二.編譯mysql動態鏈接庫 Qt版本&#xff1a;5.14.2 MySql版本&#xff1a;8.0.41 一. 安裝MySql 參考這里進行安裝&#xff1a;https://blog.csdn.net/qq_30150579/article/details/146042922 將mysql安裝目錄里的bin&#xff0c;include和lib拷貝出來…

淺論數據庫聚合:合理使用LambdaQueryWrapper和XML

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言一、數據庫聚合替代內存計算&#xff08;關鍵優化&#xff09;二、批量處理優化四、區域特殊處理解耦五、防御性編程增強 前言 技術認知點&#xff1a;使用 XM…

Ubuntu 22.04安裝NVIDIA A30顯卡驅動

一、安裝前準備 1.禁用Nouveau驅動 Ubuntu默認使用開源Nouveau驅動&#xff0c;需要手動禁用&#xff1a; vim /etc/modprobe.d/blacklist-nouveau.conf # 添加以下內容&#xff1a; blacklist nouveau options nouveau modeset0 # 更新內核并重啟&#xff1a; update-initr…

Docker Desktop 4.38 安裝與配置全流程指南(Windows平臺)

一、軟件定位與特性 Docker Desktop 是容器化應用開發與部署的一體化工具&#xff0c;支持在本地環境創建、管理和運行Docker容器。4.38版本新增GPU加速支持、WSL 2性能優化和Kubernetes 1.28集群管理功能&#xff0c;適用于微服務開發、CI/CD流水線搭建等場景。 二、安裝環境…

音視頻入門基礎:RTP專題(15)——FFmpeg源碼中,獲取RTP的視頻信息的實現

一、引言 通過FFmpeg命令可以獲取到SDP文件描述的RTP流的視頻壓縮編碼格式、色彩格式&#xff08;像素格式&#xff09;、分辨率、幀率信息&#xff1a; ffmpeg -protocol_whitelist "file,rtp,udp" -i XXX.sdp 本文以H.264為例講述FFmpeg到底是從哪個地方獲取到這…

深度學習---卷積神經網絡

一、卷積尺寸計算公式 二、池化 池化分為最大池化和平均池化 最常用的就是最大池化&#xff0c;可以認為最大池化不需要引入計算&#xff0c;而平均池化需要引出計算&#xff08;計算平均數&#xff09; 每種池化還分為Pooling和AdaptiveAvgPool Pooling(2)就是每2*2個格子…

netty中Future和ChannelHandler

netty中的Future&#xff0c;繼承自 jdk中的Future&#xff0c;&#xff0c; jdk中的Future&#xff0c;很垃圾&#xff0c;只能同步阻塞獲取結果&#xff0c;&#xff0c;&#xff0c; netty中的Future進行了升級&#xff0c;&#xff0c;可以addListener()異步獲取結果&…

java 初學知識點總結

自己總結著玩 1.基本框架 public class HelloWorld{ public static void main(String[] args){ }//類名用大寫字母開頭 } 2.輸入&#xff1a; (1)Scanner:可讀取各種類型&#xff0c;字符串相當于cin>>; Scanner anew Scanner(System.in); Scan…

質量屬性場景描述

為了精確描述軟件系統的質量屬性&#xff0c;通常采用質量屬性場景&#xff08;Quality Attribute Scenario&#xff09;作為描述質量屬性的手段。質量屬性場景是一個具體的質量屬性需求&#xff0c;使利益相關者與系統的交互的簡短陳述。 質量屬性場景是一種用于描述系統如何…

數據可攜帶權的多重價值與實踐思考

文章目錄 前言一、數據可攜帶權的提出與立法二、數據可攜帶權的多重價值1、推動數據要素市場化配置2、促進市場競爭與創新3、強化個人數據權益 三、數據可攜帶權的實踐挑戰1、數據安全與隱私保護面臨風險2、接口差異導致數據遷移成本高昂3、可攜帶的數據范圍尚存爭議 數據可攜帶…

藍橋每日打卡--分考場

#藍橋#JAVA#分考場 題目描述 n個人參加某項特殊考試。 為了公平&#xff0c;要求任何兩個認識的人不能分在同一個考場。 求是少需要分幾個考場才能滿足條件。 輸入描述 輸入格式&#xff1a; 第一行&#xff0c;一個整數n(1≤n≤100)&#xff0c;表示參加考試的人數。 …

RMAN備份bug-審計日志暴漲(select action from gv$session)

問題概述 /oracle 文件系統使用率過大&#xff0c;經過檢查是審計日志過大,/oracle 目錄 197G 審計日志占用70G&#xff0c;每6個小時產生大量審計日志&#xff0c;日志內容全是select action from gv$session &#xff0c;猜測可能跟備份有關&#xff0c; $>df -h /oracle…

在Blender中給SP分紋理組

在Blender中怎么分SP的紋理組/紋理集 其實紋理組就是材質 把同一組的材質分給同一組的模型 導入到sp里面自然就是同一個紋理組 把模型導入SP之后 就自動分好了

Nuxt:Nuxt3框架中onBeforeMount函數 和onBeforeRouteUpdate函數區別介紹 【超詳細!】

提示&#xff1a;在 Nuxt3 中&#xff0c;onBeforeMount 和 onBeforeRouteUpdate 是兩個不同場景下使用的鉤子函數&#xff0c;分別對應 Vue 組件生命周期 和 路由導航守衛。以下是它們的詳細解釋和對比&#xff1a; 文章目錄 一、onBeforeMount&#xff08;Vue 生命周期鉤子&a…

華為 Open Gauss 數據庫在 Spring Boot 中使用 Flyway

db-migration&#xff1a;Flyway、Liquibase 擴展支持達夢&#xff08;DM&#xff09;、南大通用&#xff08;GBase 8s&#xff09;、OpenGauss 等國產數據庫。部分數據庫直接支持 Flowable 工作流。 開源代碼倉庫 Github&#xff1a;https://github.com/mengweijin/db-migrat…

java 查找兩個集合的交集部分數據

利用了Java 8的Stream API&#xff0c;代碼簡潔且效率高 import java.util.stream.Collectors; import java.util.List; import java.util.HashSet; import java.util.Set;public class ListIntersection {public static List<Long> findIntersection(List<Long> …

雙足機器狗開發:Rider - Pi

雙足機器狗開發:Rider - Pi https://github.com/YahboomTechnology/Rider-Pi-Robot 項目介紹 Rider - Pi是一款為開發者、教育工作者和機器人愛好者設計的桌面雙輪腿式機器人,它基于樹莓派CM4核心模塊構建,具備多種先進功能和特點: 硬件特性 核心模塊:采用樹莓派CM4核…

Android12 添加開機鈴聲

系統默認是沒有播放開機鈴聲的功能&#xff0c;MTK有一套自己的開機鈴聲處理邏輯&#xff0c;代碼在/vendor/mediatek/proprietary/operator/frameworks/bootanimation/MtkBootanimation下&#xff0c;但是在10之后MTK就不在維護這部分代碼了。直接使用會有很多編譯報錯&#x…

3.6V-30V寬壓輸入降壓同步IC內置MOS,電流4A/5A/6A,可以滿足汽車應急電源,BMS電池,電池組USB口輸出等儲能應用

今天給大家介紹一下這三款產品&#xff0c;分別是CJ92340,輸入電壓4.5V-30V&#xff0c;輸出可調&#xff0c;電流負載能力可達4A&#xff0c;頻率350KHZ。CJ92350,輸入電壓3.6V-30V&#xff0c;輸出可調&#xff0c;頻率可調&#xff0c;帶載能力達5A。CJ92360,輸入電壓3.6V-3…

代碼隨想錄算法訓練營第35天 | 01背包問題二維、01背包問題一維、416. 分割等和子集

一、01背包問題二維 二維數組&#xff0c;一維為物品&#xff0c;二維為背包重量 import java.util.Scanner;public class Main{public static void main(String[] args){Scanner scanner new Scanner(System.in);int n scanner.nextInt();int bag scanner.nextInt();int[…