洛谷P1119 災後重建 題解 Floyd演算法
阿新 • • 發佈:2021-11-18
題目連結: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; }