题目链接:https://www.luogu.com.cn/problem/P1119
解题思路:
floyd变种题。主要要了解floyd算法的本质就是dp,状态 \(f_{i,j}\) 其实是状态 \(f_{i,j,k}\) 的状态压缩,表示 \(i\) 与 \(j\) 仅由前 \(k\) 个点(或者可以想象成仅由一个序列的点,而序列的最后一个点是 \(k\))的最短路径长度。据此可以根据时间来更新 \(k\) 即状态 \(f_{i,j}\)。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 202;
int n, m, q, t[maxn], f[maxn][maxn], p;
bool ok[maxn];
int main() {
ios::sync_with_stdio(0);
cin >> n >> m;
for (int i = 0; i < n; i ++) cin >> t[i];
memset(f, 0x3f, sizeof(f));
for (int i = 0; i < n; i ++) f[i][i] = 0;
while (m --) {
int u, v, w;
cin >> u >> v >> w;
f[u][v] = f[v][u] = w;
}
cin >> q;
while (q --) {
int x, y, tt;
cin >> x >> y >> tt;
while (p < n && t[p] <= tt) {
ok[p] = true;
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j ++) {
f[i][j] = min(f[i][j], f[i][p] + f[p][j]);
}
}
p ++;
}
if (!ok[x] || !ok[y] || f[x][y] == 0x3f3f3f3f)
cout << -1 << endl;
else
cout << f[x][y] << endl;
}
return 0;
}