迪傑斯特拉dijkstra算法總結


總結分析

  1. 總共分成兩步
    • 第一步:尋找一個這次要確認的結點
    • 第二步:利用這次確認的結點,對所有未確認結點到源點的距離進行松弛
      • 松弛:比如原本記錄源點到結點4的距離為6,這次確認了結點2,源點到結點2距離為2,結點2到結點4的距離為3,總距離為5,即可更新結點4到源點的距離
  2. 二維數組G,記錄結點間的距離;數組confirmed,記錄結點是否被確認,初始化為false;數組dis,記錄結點到源點的距離,初始化為inf(無限大)
  3. 進入dijkstra算法前先確定源點source,我們就可以確認源點到源點的距離dis[source]=0
  4. 第一個for循環,只需要確認n-1個結點即可,因為確定第n-1個結點后,會更新第n個結點到源點的距離
  5. 第二個for循環,尋找這次要確認的結點,要滿足兩個條件
    • 該結點未被確認
    • 該結點到源點的距離是目前已知所有距離中最小的
  6. 第三個for循環,利用這次確認的結點,對所有未確認的結點到源點的距離進行松弛

注意

  • 時間復雜度O(n²)
  • 單源最短路徑
  • 解決不了負權圖,有可能出錯

題目

從0點出發,尋找到達每一個結點的最短路徑(單源最短路徑問題

代碼

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define n 7
#define inf 233
vector<vector<int>> G(n, vector<int>(n,inf));
vector<int> dijkstra(vector<vector<int>>, int source) {
	vector<bool> confirmed(n, false);
	vector<int> dis(n, inf);
	dis[source] = 0;
	for (int i = 0; i < n - 1; i++) {
		int curr=-1;
		for (int j = 0; j < n; j++) {
			if (!confirmed[j] && (curr == -1 || dis[curr] > dis[j])) curr = j;
		}
		confirmed[curr] = true;
		for (int j = 0; j < n; j++) {
			if(!confirmed[j]&&dis[j]>G[curr][j]+dis[curr]) dis[j] = G[curr][j]+dis[curr];
		}
	}
	return dis;
}

int main() {
	G[0][2] = 2;
	G[0][1] = 5;
	G[1][3] = 1;
	G[1][4] = 6;
	G[1][0] = 5;
	G[2][3] = 6;
	G[2][5] = 8;
	G[2][0] = 2;
	G[3][2] = 6;
	G[3][1] = 1;
	G[3][4] = 1;
	G[3][5] = 2;
	G[4][1] = 6;
	G[4][3] = 1;
	G[4][6] = 7;
	G[5][2] = 8;
	G[5][3] = 2;
	G[5][6] = 3;
	G[6][4] = 7;
	G[6][5] = 3;

	vector<int> ans = dijkstra(G, 0);
	for (auto a : ans) cout << a << " ";
	cout << endl;

	return 0;
}

結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM