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;
}