弗洛伊德floyd算法總結


總結分析

  1. 是一個簡單的dp
  2. 迪傑斯特拉算法,不斷對兩個結點之間的距離進行松弛
    • 松弛:比如原本記錄結點1到結點4的距離為6,這次k是結點2,結點1到結點2距離為2,結點2到結點4的距離為3,總距離為5,即可更新結點1到結點4的距離
  3. 還不是很懂dp,所以不太會解釋
  4. 結點k是結點i和j之間的中轉站

注意

  • 時間復雜度O(n³)
  • 多源最短路徑,其實可以對每個結點使用一次dijstra算法,也是(n³),只是使用floyd算法代碼長度短很多且易於理解
  • 可以解決負權圖,不能解決負環圖
  • 為什么d[i][k]是最小的:因為假設有k1<k,我們會有d[i][k]=min(d[i][k],d[i][k1]+d[k1][k]),輪到d[i][k]就說明之前已經確定它是最小的了

題目

求每一個頂點之間的最短路徑

代碼

#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
using namespace std;
#define n 7
#define inf 233
vector<vector<int>> G(n, vector<int>(n, inf));
void floyd() {
	for (int k = 0; k < n; k++) {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				G[i][j] = min(G[i][j], G[i][k] + G[k][j]);
			}
		}
	}
}

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;
        //對角線為0
	for (int i = 0; i < n; i++) G[i][i] = 0;

	for (auto a : G) {
		for (auto b : a) {
                        //如果是inf233,改為輸出-1
			if (b == 233) cout << setw(2) << -1 << " ";
			else cout << setw(2) << b << " ";
		}
		cout << endl;
	}

	floyd();

	cout << endl << "完成floyd算法后" << endl;

	for (auto a : G) {
		for (auto b : a) {
			cout << setw(2) << b << " ";
		}
		cout << endl;
	}

	return 0;
}

結果


免責聲明!

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



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