最短路徑之Floyd

Floyd本質上就是通過前k個節點來更新i和j之間的最短路徑。

20191213更新:

關於爲什麼k放在最外層:
在這裏插入圖片描述

關於爲什麼k能省略:
在這裏插入圖片描述

這個困擾了我好久, 最後, 終於想通了。。。說白點, 就是f[k][i][k] = f[k - 1][i][k], f[k][k][j] = f[k - 1][k][j]若這兩者不等, 說明圖中存在負環, 而存在負環就不能用Floyd。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 2e2 + 10;
const int inf = 1e9 + 10;
int f[maxn][maxn];
int a[maxn];
int n, m;

void floyd(int k) {
	for(int i = 0; i < n; i++) {
		for(int j = 0; j < n; j++) {
			if(f[i][k] + f[k][j] < f[i][j]) {
				f[i][j] = f[i][k] + f[k][j];
			}
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	fill(f[0], f[0] + maxn * maxn, inf);
	for(int i = 0; i < n; i++)
		f[i][i] = 0;
	cin >> n >> m;
	for(int i = 0; i < n; i++)
		cin >> a[i];
	int x, y, z;
	for(int i = 1; i <= m; i++) {
		cin >> x >> y >> z;
		f[x][y] = z;
		f[y][x] = z;
	}
	cin >> m;
	int now = 0;
	while(m--) {
		cin >> x >> y >> z;
		while(a[now] <= z && now < n) {
			floyd(now);
			now++;
		}
//		cout << a[x] << ' ' << a[y] << " " << f[x][y] << endl;
		if(a[x] > z || a[y] > z || f[x][y] == inf) {
			cout << -1 << endl;
		}
		else
			cout << f[x][y] << endl;
	}
	return 0;
}
發佈了95 篇原創文章 · 獲贊 18 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章