青蛙從石頭 1 跳到石頭 2,每次跳躍距離為兩石頭間歐氏距離。求路徑中最長單次跳躍距離最小的值(即「最小化最大邊權路徑」)。
在無向圖中,任意兩點間的最小最大邊權路徑,其最大邊權等於最小生成樹 (MST) 上該兩點路徑的最大邊權。證明:MST 的任意兩點路徑為所有路徑中字典序最小的邊權序列(瓶頸最短路性質)。
struct Edge {
int u, v;
double w;
bool operator<(const Edge& other) const { return w < other.w; }
};
vector edges;
vector> mst[MAXN]; // MST 鄰接表
int parent[MAXN];
int find(int x) { return parent[x]==x ? x : parent[x]=find(parent[x]); }
void kruskal(int n) {
sort(edges.begin(), edges.end());
for (int i=1; i<=n; ++i) parent[i]=i;
int cnt = 0;
for (auto& e : edges) {
int fu=find(e.u), fv=find(e.v);
if (fu != fv) {
parent[fu] = fv;
mst[e.u].push_back({e.v, e.w});
mst[e.v].push_back({e.u, e.w});
if (++cnt == n-1) break;
}
}
}
double dfs(int u, int target, int fa, double curMax) {
if (u == target) return curMax;
for (auto [v, w] : mst[u]) {
if (v != fa) {
double ans = dfs(v, target, u, max(curMax, w));
if (ans >= 0) return ans;
}
}
return -1;
}
dist[v] = min(dist[v], max(dist[u], w(u,v))),O(n²) 求 1 到所有點的最小最大邊權printf("%.3f\n\n", ans) 注意雙換行n=0 結束POJ 2253 是 MST 瓶頸路徑性質的直接應用。理解「MST 上任意兩點路徑為所有路徑中最大邊權最小」是解決此類問題的關鍵。對於 n≤200 的完全圖,Kruskal 代碼簡潔;大規模稠密圖首選 Prim 優化版或修改版 Dijkstra。