弗洛伊德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;
}

结果

posted @ 2020-10-11 22:09  肥斯大只仔  阅读(1183)  评论(0编辑  收藏  举报