【數據結構】B : DS圖應用--最短路徑

B : DS圖應用–最短路徑

文章目錄

  • B : DS圖應用--最短路徑
    • Description
    • Input
    • Output
    • Sample
        • Input
      • Output
    • 解題思路:
      • 初始化
      • 主循環
      • 心得:
    • AC代碼

Description

給出一個圖的鄰接矩陣,再給出指定頂點v0,求頂點v0到其他頂點的最短路徑

Input

第一行輸入t,表示有t個測試實例
第二行輸入n,表示第1個圖有n個結點
第三行起,每行輸入鄰接矩陣的一行,以此類推輸入n行
第i個結點與其他結點如果相連則為1,無連接則為0,數據之間用空格隔開
第四行輸入v0,表示求v0到其他頂點的最短路徑距離
以此類推輸入下一個示例

Output

每行輸出v0到某個頂點的最短距離和最短路徑
每行格式:v0編號-其他頂點編號—-[最短路徑],具體請參考示范數據

Sample

Input
1
5
0 5 0 7 15
0 0 5 0 0
0 0 0 0 1
0 0 2 0 0
0 0 0 0 0
0

Output

0-1-5----[0 1 ]
0-2-9----[0 3 2 ]
0-3-7----[0 3 ]
0-4-10----[0 3 2 4 ]

解題思路:

首先先要了解圖論里面單源最短路徑的實現——Dijkstra算法,知道它是怎么一步步算出源點到每一個點的最短距離的,可以參考這個視頻【算法】最短路徑查找—Dijkstra算法,然后就看代碼,對著視頻來進行解釋:

// Dijkstra算法實現
void Dijkstra(int start)
{memset(dis, 0x3f, sizeof(dis));memset(fixed, 0, sizeof(fixed));last[start] = -1;dis[start] = 0;int minDisNode, minDis;for (int i = 0; i < n; i++){minDis = INF;for (int j = 0; j < n; j++)if (!fixed[j] && dis[j] < minDis)minDisNode = j, minDis = dis[j];fixed[minDisNode] = true;for (int j = 0; j < n; j++){if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])dis[j] = minDis + g[minDisNode][j], last[j] = minDisNode;}}return 0;
}

初始化

memset(dis, 0x3f, sizeof(dis));  // 設置所有節點到源點的初始距離為無窮大
memset(fixed, 0, sizeof(fixed)); // 初始化所有節點為未固定
last[start] = -1;                // 源點的上一個節點設置為-1
dis[start] = 0;                  // 源點到自身的距離設置為0
  • dis[]數組存儲從源點到每個節點的當前最短距離。初始時,除了源點到自身的距離為0外,所有其他距離都設置為無窮大。
  • fixed[]數組用于標記節點是否已經找到了從源點出發的最短路徑。
  • last[]數組用于記錄到達每個節點的最短路徑上的前一個節點,對于源點而言,沒有前一個節點,所以設置為-1。

主循環

for (int i = 0; i < n; i++)
{minDis = INF;for (int j = 0; j < n; j++)if (!fixed[j] && dis[j] < minDis)minDisNode = j, minDis = dis[j];fixed[minDisNode] = true;for (int j = 0; j < n; j++){if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])dis[j] = minDis + g[minDisNode][j], last[j] = minDisNode;}
}
  • 第一個for循環遍歷所有節點,尋找最短路徑。
  • 內層的第一個for循環用于找到當前未固定節點中距離源點最近的節點minDisNode
  • fixed[minDisNode] = true;將找到的最短距離節點標記為已固定。
  • 內層的第二個for循環進行“松弛操作”:通過minDisNode更新其他未固定節點的最短距離。如果通過minDisNode到某個節點的距離比當前記錄的距離短,則更新該距離
  • 松弛操作:if (g[minDisNode][j] != 0 && minDis + g[minDisNode][j] < dis[j])檢查是否存在一條從minDisNodej的邊,并且通過這條邊到達j的距離是否比當前記錄的距離短。如果是,更新dis[j]為通過minDisNodej的新距離,并記錄last[j]minDisNode

心得:

一開始學這個算法的時候,可能會想到一個環,對于這個環,例如一個三個節點的環,現在節點一是源點,懵的地方就在于我在第一個次循環之后得出節點一到節點二最短,我就把節點二納入fixed中,我就有疑惑,如果是一個環的話,那我從節點一到節點三再到節點二為什么不是最短。現在項想明白,在循環內層第一個for循環的時候,就已經挑選出最短的了,哪怕節點一到節點二和節點一到節點三的距離相等,節點三到節點二總不可能為負數吧。

明白這個算法的原理之后,后面的輸出就很簡單了,直接上代碼吧。

AC代碼

#include <iostream>
#include <vector>
using namespace std;const int INF = 999999; // 定義無窮大常量void printShortestPath(int u, const vector<int>& previousNodes) {if (u == -1)return;printShortestPath(previousNodes[u], previousNodes);cout << u << " ";return;
}void calculateShortestPaths(int start, const vector<vector<int>>& graph, int n) {vector<int> previousNodes(n, -1);vector<int> shortestDistances(n, INF);vector<int> visitedNodes(n, 0);shortestDistances[start] = 0;for (int i = 0; i < n; i++) {int minDistance = INF, nearestNode = -1;for (int j = 0; j < n; j++)if (!visitedNodes[j] && shortestDistances[j] < minDistance){nearestNode = j;minDistance = shortestDistances[j];}visitedNodes[nearestNode] = 1;for (int j = 0; j < n; j++)if (graph[nearestNode][j] != 0 && minDistance + graph[nearestNode][j] < shortestDistances[j]){shortestDistances[j] = minDistance + graph[nearestNode][j];previousNodes[j] = nearestNode;}}for (int i = 0; i < n; i++) {if (i != start) {cout << start << "-" << i << "-" << shortestDistances[i];cout << "----[";printShortestPath(i, previousNodes);cout << "]" << endl;}}return;
}int main() {int t;cin >> t;while (t--) {int n;cin >> n;vector<vector<int>> graph(n, vector<int>(n));for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)cin >> graph[i][j];int sourceNode;cin >> sourceNode;calculateShortestPaths(sourceNode, graph, n);}return 0;
}

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

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

相關文章

SkyWalking配置報警推送到企業微信

1、先在企業微信群里創建一個機器人&#xff0c;復制webhook的地址&#xff1a; 2、找到SkyWalking部署位置的alarm-settings.yml文件 編輯&#xff0c;在最后面加上此段配置 &#xff01;&#xff01;&#xff01;一定格式要對&#xff0c;不然一直報警報不出來按照網上指導…

JVM 堆外內存詳解

Java 進程內存占用除了JVM 運行時數據區&#xff0c;還有直接內存&#xff08;Direct Memory&#xff09;區域及 JVM 程序自身也會占用內存 直接內存&#xff08;Direct Memory&#xff09;區域&#xff1a;直接內存通過使用Native堆外內存來存儲數據&#xff0c;這意味著數據…

大數據平臺實踐之CDH6.2.1+spark3.3.0+kyuubi-1.6.0

前言&#xff1a;關于kyuubi的原理和功能這里不做詳細的介紹&#xff0c;感興趣的同學可以直通官網&#xff1a;https://kyuubi.readthedocs.io/en/v1.7.1-rc0/index.html 下載軟件版本 wget http://distfiles.macports.org/scala2.12/scala-2.12.16.tgz wget https://archi…

pikachu_php反序列化

pikachu_php反序列化 源代碼 class S{var $test "pikachu";function __construct(){echo $this->test;} }//O:1:"S":1:{s:4:"test";s:29:"<script>alert(xss)</script>";} $html; if(isset($_POST[o])){$s $_POST[…

基于python人臉性別年齡檢測系統-深度學習項目

歡迎大家點贊、收藏、關注、評論啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代碼。 文章目錄 一項目簡介簡介技術組成1. OpenCV2. Dlib3. TensorFlow 和 Keras 功能流程 二、功能三、系統四. 總結 一項目簡介 # Python 人臉性別年齡檢測系統介紹 簡介 該系統基…

用idea搭建一個spring cloud微服務項目

以下是使用 IntelliJ IDEA 搭建 Spring Cloud 微服務項目的步驟&#xff1a; 創建一個新的 Maven 項目。 在 pom.xml 文件中添加以下依賴&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-…

Android studio 遷移之后打開沒反應

把Android studio由d盤遷移到c盤&#xff0c;點擊沒反應&#xff1b; 需要把C:\Users\xxxx\AppData\Roaming\Google\AndroidStudio2022.3 目錄下的studio64.exe.vmoptions 修改為C:&#xff0c;刪除該文件會導致無法安裝app。 里面配置了一個

SpringMVC問題

文章目錄 SpringMVC運行流程MVC的概念與請求在MVC中的執行路徑&#xff0c;ResponsBody注解的用途SpringMVC啟動流程 SpringMVC運行流程 ? 客戶端&#xff08;瀏覽器&#xff09;發送請求&#xff0c;直接請求到 DispatcherServlet 。 ? DispatcherServlet 根據請求信息調用 …

SpringBoot問題

文章目錄 Springboot特性 Springboot特性 自動裝配&#xff1a;提供自動配置的“starter”項目對象模型&#xff08;POMS&#xff09;以簡化Maven配置。比如使用 MongoDB 時&#xff0c;只需加入 MongoDB 的 Starter 包&#xff0c;然后配置 的連接信息&#xff0c;就可以直接使…

【React-Router】路由導航

1. 概念 路由系統中的多個路由之間需要進行路由跳轉&#xff0c;并且在跳轉的同時有可能需要傳遞參數進行通信。 2. 聲明式導航 // /page/Login/index.jsimport { Link } from react-router-dom const Login () > {return <div>登錄頁{/* 解析成 a 鏈接 */}<Li…

php獲取表單以POST方式或GET方式提交的值

在php中存在兩個全局變量&#xff08;數組&#xff09;&#xff0c;其中$_GET數組用來記錄表單通過GET方式提交的數據&#xff0c;$_POST數組用來記錄表單通過POST方式提交的數據。 一、php獲取GET方式提交的值 在php中通過以下代碼來獲取&#xff1a; $_GET[name] //nam…

Windows平臺如何實現RTSP流二次編碼并添加動態水印后推送RTMP或輕量級RTSP服務

技術背景 我們在對接RTSP播放器相關的技術訴求的時候&#xff0c;遇到這樣的需求&#xff0c;客戶做特種設備巡檢的&#xff0c;需要把攝像頭拍到的RTSP流拉下來&#xff0c;然后添加動態水印后&#xff0c;再生成新的RTSP URL&#xff0c;供平臺調用。真個流程需要延遲盡可能…

Anthropic LLM論文閱讀筆記

研究時間&#xff1a;與Instrcut GPT同期的工作&#xff0c;雖然其比ChatGPT發布更晚&#xff0c;但是其實完成的時間比ChatGPT更早。與ChatGPT的應用區別&#xff1a;該模型比ChatGPT回答我不知道的概率更高。將強化學習用于大語言模型&#xff08;RLHF&#xff09;&#xff1…

6.基于蜻蜓優化算法 (DA)優化的VMD參數(DA-VMD)

代碼原理 基于蜻蜓優化算法 (Dragonfly Algorithm, DA) 優化的 VMD 參數&#xff08;DA-VMD&#xff09;是指使用蜻蜓優化算法對 VMD 方法中的參數進行自動調優和優化。 VMD&#xff08;Variational Mode Decomposition&#xff09;是一種信號分解方法&#xff0c;用于將復雜…

【數據結構】鏈表中二級指針的應用

&#x1f984;個人主頁:修修修也 &#x1f38f;所屬專欄:數據結構 ??操作環境:Visual Studio 2022 (注:為方便演示本篇使用的x86系統,因此指針的大小為4個字節) 目錄 &#x1f4cc;形參的改變不影響實參! 1.調用函數更改整型時傳值調用與傳址調用的區別 &#x1f38f;傳值…

微服務學習|初識Docker、使用Docker、自定義鏡像、DockerCompose、Docker鏡像倉庫

初識Docker 項目部署的問題 大型項目組件較多&#xff0c;運行環境也較為復雜&#xff0c;部署時會碰到一些問題 依賴關系復雜&#xff0c;容易出現兼容性問題 開發、測試、生產環境有差異 Docker如何解決依賴的兼容問題的? 將應用的Libs (函數庫)、Deps (依賴)配置與應用…

線性回歸的正則方法:嶺回歸和Lasso

線性回歸的正則方法包括嶺回歸&#xff08;Ridge Regression&#xff09;和Lasso回歸&#xff08;Least Absolute Shrinkage and Selection Operator Regression&#xff09;。這兩種方法都是為了解決線性回歸中可能存在的過擬合問題而提出的。 選擇使用嶺回歸還是Lasso回歸通常…

使用 goland 開發 golang 項目環境配置

方式1&#xff1a;使用 GOPATH 和 GOROOT 在 goland 中打開&#xff1a;Settings - Go&#xff0c;會看到 GOROOT、GOPATH&#xff0c;其相關解釋與配置如下&#xff1a; GOROOT&#xff1a;對應 go 的安裝路徑&#xff0c;例如&#xff1a;D:\go\binGOPATH&#xff1a;是我們…

JavaScript中的事件循環 為什么是微任務先運行

無意中看到這個問題&#xff0c;以下是個人的看法 1、性能和響應性&#xff1a; 微任務通常比宏任務執行得更快&#xff0c;因為微任務通常涉及更少的工作量。將微任務放在宏任務之前可以盡早執行那些需要快速響應的任務&#xff0c;提高系統的響應性能。 2、Promise 的異步特…

3d標簽云實現過程(tagcloud.js)同步原生和 vue

寫在前面 本來是沒有準備寫這個知識點&#xff0c;但是下載這個 js 的時候發現很多都是要錢或者是積分的&#xff0c;我就不明白了一個開源了這么久的 js 怎么還有人拿來掙錢的&#xff0c;同時還有一些只有原生 html 的例子&#xff0c;但是現在都是 框架主導的一些項目&#…