Dijkstra 算法代碼步驟[leetcode.743網絡延遲時間]

有?n?個網絡節點,標記為?1?到?n

給你一個列表?times,表示信號經過?有向?邊的傳遞時間。?times[i] = (ui, vi, wi),其中?ui?是源節點,vi?是目標節點,?wi?是一個信號從源節點傳遞到目標節點的時間。

現在,從某個節點?K?發出一個信號。需要多久才能使所有節點都收到信號?如果不能使所有節點收到信號,返回?-1?。

示例 1:

輸入:times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2
輸出:2

算法流程

  1. 初始化

    • 鄰接矩陣?g?存儲邊權。

    • dis?數組存儲源點到各點的最短距離,初始為?INF

    • done?數組標記節點是否已確定最短路徑。

  2. Dijkstra 主循環

    • 選擇當前未處理的、距離最短的節點?x

    • 如果?x?不可達,返回?-1

    • 更新?maxDis?為?dis[x](因為?dis[x]?是遞增的)。

    • 標記?x?為已處理。

    • 松弛?x?的所有鄰居?y,更新?dis[y]

  3. 終止條件

    • 所有節點已處理,返回?maxDis(最長延遲時間)。

時間復雜度

  • 鄰接矩陣實現O(n^2)(適用于稠密圖)。

  • 堆優化(優先隊列)O(E log V)(適用于稀疏圖,但本題未使用)。

空間復雜度

  • O(n^2)(鄰接矩陣存儲)。

1. 初始化

final int INF = Integer.MAX_VALUE / 2; // 防止加法溢出
int[][] g = new int[n][n]; // 鄰接矩陣
for (int[] row : g) {Arrays.fill(row, INF);
}
  • INF:表示“無窮大”,用于初始化不可達的邊。Integer.MAX_VALUE / 2?是為了防止后續計算?dis[x] + g[x][y]?時溢出。

  • g:鄰接矩陣,g[i][j]?表示從節點?i?到?j?的傳輸時間(權重)。

  • 初始化鄰接矩陣:所有邊初始為?INF(表示初始時所有節點之間不可達)。


2. 構建圖的鄰接矩陣

for (int[] t : times) {g[t[0] - 1][t[1] - 1] = t[2];
}
  • times?是一個二維數組,其中?times[i] = [u, v, w]?表示從節點?u?到?v?的傳輸時間為?w

  • 存儲到鄰接矩陣

    • g[t[0] - 1][t[1] - 1] = t[2]:因為節點編號從?1?開始,而數組索引從?0?開始,所以需要?-1?調整。


3. Dijkstra 算法初始化

int maxDis = 0;
int[] dis = new int[n];
Arrays.fill(dis, INF);
dis[k - 1] = 0;
boolean[] done = new boolean[n];
  • maxDis:記錄所有最短路徑中的最大值(即網絡延遲時間)。

  • disdis[i]?表示從源節點?k?到節點?i?的最短距離,初始為?INF(不可達)。

  • dis[k - 1] = 0:源節點到自身的距離為?0

  • done:標記節點是否已經確定最短路徑。


4. Dijkstra 主循環

while (true) {int x = -1;for (int i = 0; i < n; i++) {if (!done[i] && (x < 0 || dis[i] < dis[x])) {x = i;}}if (x < 0) {return maxDis; // 所有節點已處理完畢}if (dis[x] == INF) { // 有節點無法到達return -1;}maxDis = dis[x]; // 更新最大延遲時間done[x] = true; // 標記 x 的最短路徑已確定for (int y = 0; y < n; y++) {dis[y] = Math.min(dis[y], dis[x] + g[x][y]);}
}

(1) 選擇當前未處理的最短路徑節點

int x = -1;
for (int i = 0; i < n; i++) {if (!done[i] && (x < 0 || dis[i] < dis[x])) {x = i;}
}
  • x:當前未處理(!done[i])且距離?dis[i]?最小的節點。

  • 貪心策略:每次選擇距離源節點最近的未處理節點進行擴展。

(2) 檢查是否所有節點已處理

if (x < 0) {return maxDis; // 所有節點已處理完畢
}
  • x < 0:表示所有節點都已處理,返回?maxDis(即最長延遲時間)。

(3) 檢查是否有節點不可達

if (dis[x] == INF) { // 有節點無法到達return -1;
}
  • dis[x] == INF:表示當前節點?x?無法從源節點到達,直接返回?-1

(4) 更新?maxDis?并標記?x?為已處理

maxDis = dis[x]; // 更新最大延遲時間
done[x] = true; // 標記 x 的最短路徑已確定
  • maxDis:由于 Dijkstra 每次處理的?dis[x]?是遞增的,所以直接更新即可。

  • done[x] = true:表示?x?的最短路徑已確定,后續不再更新。

(5) 松弛操作(更新鄰居的最短距離)

for (int y = 0; y < n; y++) {dis[y] = Math.min(dis[y], dis[x] + g[x][y]);
}
  • 松弛(Relaxation):嘗試通過?x?縮短?y?的最短路徑:

    • 如果?dis[x] + g[x][y] < dis[y],則更新?dis[y]

完整版代碼:

class Solution {public int networkDelayTime(int[][] times, int n, int k) {final int INF = Integer.MAX_VALUE / 2; // 防止加法溢出int[][] g = new int[n][n]; // 鄰接矩陣for (int[] row : g) {Arrays.fill(row, INF);}for (int[] t : times) {g[t[0] - 1][t[1] - 1] = t[2];}int maxDis = 0;int[] dis = new int[n];Arrays.fill(dis, INF);dis[k - 1] = 0;boolean[] done = new boolean[n];while (true) {int x = -1;for (int i = 0; i < n; i++) {if (!done[i] && (x < 0 || dis[i] < dis[x])) {x = i;}}if (x < 0) {return maxDis; // 最后一次算出的最短路就是最大的}if (dis[x] == INF) { // 有節點無法到達return -1;}maxDis = dis[x]; // 求出的最短路會越來越大done[x] = true; // 最短路長度已確定(無法變得更小)for (int y = 0; y < n; y++) {// 更新 x 的鄰居的最短路dis[y] = Math.min(dis[y], dis[x] + g[x][y]);}}}
}

?

示例

輸入

times = [[2,1,1],[2,3,1],[3,4,1]], n = 4, k = 2

執行流程

  1. 初始化

    • dis = [INF, 0, INF, INF](源節點?k=2?的距離為?0)。

  2. 第一次循環

    • 選擇?x=1dis[1] = 0)。

    • 松弛鄰居?y=0?和?y=2

      • dis[0] = min(INF, 0 + 1) = 1

      • dis[2] = min(INF, 0 + 1) = 1

    • maxDis = 0

  3. 第二次循環

    • 選擇?x=0?或?x=2dis[0] = 1,?dis[2] = 1)。

    • 假設選?x=0,但沒有鄰居可更新。

    • maxDis = 1

  4. 第三次循環

    • 選擇?x=2

    • 松弛鄰居?y=3

      • dis[3] = min(INF, 1 + 1) = 2

    • maxDis = 1

  5. 第四次循環

    • 選擇?x=3

    • 沒有鄰居可更新。

    • maxDis = 2

  6. 結束

    • 所有節點已處理,返回?maxDis = 2

最終輸出2(最長延遲時間)。

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

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

相關文章

【java】lambda表達式總結

目錄 一、面向對象的處理方法 二、函數式編程的處理方法 先使用匿名內部類&#xff1a; lambda改造&#xff1a; lambda改造規則 示例&#xff1a; 三、補充&#xff1a;函數式接口 大家好&#xff0c;我是jstart千語。今天總結一下lambda表達式。lambda表達式在后面的s…

AtCoder Beginner Contest 242 G - Range Pairing Query (莫隊)

每周五篇博客&#xff1a;&#xff08;5/5&#xff09; 我做到了&#xff01; https://atcoder.jp/contests/abc242/tasks/abc242_g 這題主要是想給大家提供一份莫隊的板子&#xff0c;很多莫隊題基本上填空就差不多了&#xff08; 板子 void solve() {int n;std::cin >…

淘寶商品主圖標題api接口

1、輸入淘寶商品id或者鏈接&#xff0c;點查詢 2、查詢淘寶商品主圖&#xff0c;商品標題&#xff0c;商品價格&#xff0c;賣家旺旺 3、支持api接口

文心一言開發指南06——千帆大模型平臺新手指南

版權聲明 本文原創作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 千帆大模型平臺為新手用戶提供了一個全面的入門指南&#xff0c;以便用戶能夠快速熟悉平臺的操作和功能。千帆大模型平臺通過提供詳細的新手指南&#xff0c;確保用戶能夠順…

Pacman-N-queen

文檔 代碼及文檔&#xff1a;通過網盤分享的文件&#xff1a;code 鏈接: https://pan.baidu.com/s/1Rgo9ynnEqjZsSP2-6TyS8Q?pwdn99p 提取碼: n99p 補充核心代碼 核心代碼內容&#xff1a; genetic_algorithm,py # -*- coding: utf-8 -*- """ Created on …

常用的多傳感器數據融合方法

1. 概述 根據具體需求&#xff08;實時性、計算資源、噪聲特性&#xff09;選擇合適的方法&#xff0c;實際應用中常結合多種方法&#xff08;如UKF與神經網絡結合&#xff09;。 傳統方法 &#xff08;KF/EKF/UKF/PF&#xff09;依賴數學模型&#xff0c;適合動態系統&#…

簡單幾步,開啟 Intel VT-x 讓電腦“解開CPU封印”

#vmware #虛擬機 #cpu虛擬化 # Intel VT-x 前言 你是不是也遇到過這種情況&#xff1a;在嘗試運行虛擬機&#xff08;VM&#xff09;、安卓模擬器&#xff0c;或者使用 Windows 沙盒、WSL2 等功能時&#xff0c;遇到了類似“此主機支持 Intel VT-x&#xff0c;但 Intel VT-x …

Go語言--語法基礎4--基本數據類型--字符串類型

在 Go 語言中&#xff0c;字符串也是一種基本類型。相比之下&#xff0c; C/C 語言中并不存在原 生的字符串類型&#xff0c; 通常使用字符數組來表示&#xff0c;并以字符指針來傳遞。 Go 語言中字符串的聲明和初始化非常簡單&#xff0c;舉例如下&#xff1a; var str st…

QT中的事件及其屬性

Qt中的事件是對操作系統提供的事件機制進行封裝&#xff0c;Qt中的信號槽就是對事件機制的進一步封裝 但是特殊情況下&#xff0c;如對于沒有提供信號的用戶操作&#xff0c;就需要通過重寫事件處理的形式&#xff0c;來手動處理事件的響應邏輯 常見的Qt事件&#xff1a; 常見事…

socket套接字-UDP(中)

socket套接字-UDP&#xff08;上&#xff09;https://blog.csdn.net/Small_entreprene/article/details/147465441?fromshareblogdetail&sharetypeblogdetail&sharerId147465441&sharereferPC&sharesourceSmall_entreprene&sharefromfrom_link UDP服務器…

C++入門小館: STL 之queue和stack

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

ALTER TABLE 刪除DROP表列的報錯: 因為有一個或多個對象訪問此列

目錄 1.問題 2.解決辦法 1.問題 刪除某個列名的時候&#xff0c;提示錯誤因為有一個或多個對象訪問此列 2.解決辦法 2.1 添加或刪除表新列名 將表中的字段設置Default 或 NOT NULL 都會給該字段添加約束&#xff0c;增加了這些約束后&#xff0c;再SQL腳本修改類型、刪除會發生…

python源碼打包為可執行的exe文件

文章目錄 簡單的方式&#xff08;PyInstaller&#xff09;特點步驟安裝 PyInstaller打包腳本得到.exe文件 簡單的方式&#xff08;PyInstaller&#xff09; 特點 支持 Python 3.6打包為單文件&#xff08;–onefile&#xff09;或文件夾形式自動處理依賴項 步驟 安裝 PyIns…

【2025最近Java面試八股】Spring中循環依賴的問題?怎么解決的?

1. 什么是循環依賴&#xff1f; 在Spring框架中&#xff0c;循環依賴是指兩個或多個bean之間相互依賴&#xff0c;形成了一個循環引用的情況。如果不加以處理&#xff0c;這種情況會導致應用程序啟動失敗。導致 Spring 容器無法完成依賴注入。 例如&#xff1a; Service publi…

JimuBI 積木報表 v1.9.5發布,大屏和儀表盤,免費數據可視化

項目介紹 JimuBI (積木報表BI) 是一款免費的數據可視化產品&#xff0c;含大屏和儀表盤、門戶、移動圖表&#xff0c;像搭建積木一樣完全在線設計&#xff01; 大屏采用類word風格&#xff0c;可以隨意拖動組件&#xff0c;想怎么設計怎么設計&#xff0c;可以像百度和阿里一樣…

云原生課程-Docker

一次鏡像&#xff0c;到處運行。 1. Docker詳解&#xff1a; 1.1 Docker簡介&#xff1a; Docker是一個開源的容器化平臺&#xff0c;可以幫助開發者將應用程序和其依賴的環境打包成一個可移植的&#xff0c;可部署的容器。 docker daemon:是一個運行在宿主機&#xff08;DO…

HikariCP 6.3.0 完整配置與 Keepalive 優化指南

HikariCP 6.3.0 完整配置與 Keepalive 優化指南 HikariCP 是一個高性能、輕量級的 JDBC 連接池框架&#xff0c;廣泛應用于 Java 應用&#xff0c;尤其是 Spring Boot 項目。本文檔基于 HikariCP 6.3.0 版本&#xff0c;詳細介紹其功能、配置參數、Keepalive 機制以及優化建議…

基于springboot+vue的攝影師分享交流社區的設計與實現

開發語言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服務器&#xff1a;tomcat7數據庫&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;數據庫工具&#xff1a;Navicat11開發軟件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

ComfyUI for Windwos與 Stable Diffusion WebUI 模型共享修復

#工作記錄 雖然在安裝ComfyUI for Windwos時已經配置過extra_model_paths.yaml 文件&#xff0c;但升級ComfyUI for Windwos到最新版本后發現原先的模型配置失效了&#xff0c;排查后發現&#xff0c;原來是 extra_model_paths.yaml 文件在新版本中被移動到了C盤目錄下&#x…

【最新版】沃德代駕源碼全開源+前端uniapp

一.系統介紹 基于ThinkPHPUniapp開發的代駕軟件。系統源碼全開源&#xff0c;代駕軟件的主要功能包括預約代駕、在線搶單、一鍵定位、在線支付、車主登記和代駕司機實名登記等?。用戶可以通過小程序預約代駕服務&#xff0c;系統會估算代駕價格并推送附近代駕司機供用戶選擇&…