無向圖,邊有權值(噪音強度)。多次查詢:從 s 到 t,路徑上最大邊權最小化。不可達輸出 no path。C ≤ 100,S 條邊,Q 次查詢。
這是經典的瓶頸路徑問題。定義 dist[i][j] = 從 i 到 j 的路徑中最大邊權的最小值。
遞推:dist[i][j] = min(dist[i][j], max(dist[i][k], dist[k][j]))。
這正是 Floyd-Warshall 的變體:將 + 換為 max,min 保持不變。
dist[i][j] = INF (i≠j),dist[i][i] = 0,邊 dist[u][v] = dist[v][u] = w。dist[i][j] = min(dist[i][j], max(dist[i][k], dist[k][j]))dist[s][t](若為 INF 輸出 no path)。
#include
using namespace std;
const int MAXN = 105;
const int INF = 0x3f3f3f3f;
int dist[MAXN][MAXN];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int C, S, Q, tc = 0;
while (cin >> C >> S >> Q, C||S||Q) {
if (tc++) cout << '\n';
for (int i = 1; i <= C; i++)
for (int j = 1; j <= C; j++)
dist[i][j] = (i==j) ? 0 : INF;
for (int i = 0; i < S; i++) {
int u, v, w; cin >> u >> v >> w;
dist[u][v] = dist[v][u] = min(dist[u][v], w);
}
for (int k = 1; k <= C; k++)
for (int i = 1; i <= C; i++)
for (int j = 1; j <= C; j++)
if (dist[i][k] != INF && dist[k][j] != INF)
dist[i][j] = min(dist[i][j], max(dist[i][k], dist[k][j]));
cout << "Case #" << tc << '\n';
while (Q--) {
int u, v; cin >> u >> v;
if (dist[u][v] == INF) cout << "no path\n";
else cout << dist[u][v] << '\n';
}
}
return 0;
}
UVA 10048 是 Floyd-Warshall 變體的經典例題:路徑代價 = 最大邊權,目標 = 最小化代價。只需將標準 Floyd 的 d[i][j] = min(d[i][j], d[i][k]+d[k][j]) 改為 d[i][j] = min(d[i][j], max(d[i][k], d[k][j]))。掌握此變體,可解決大類「瓶頸路徑」、「最小化最大代價」問題。