Star Way To Heaven 題解
阿新 • • 發佈:2020-08-16
題目連結
分析
此題可以暴力二分,但是隻有80pts,所以不採納這個思想。
考慮與最小生成樹的關係,當所有的引力把能走的路全部封死之後,此時的\(ans\)便是最大的引力圈的半徑。
step1
首先初始化\(dis[i] = m - y[i]\),把dis[k+1]設為m。
step2
然後用\(Prim\)不停遍歷,如果此時找的最近節點為\(k+1\)說明已經遍歷完畢,直接退出,
ans更新成ans與dis[falg]之間的大者。
然後更xin\(dis[i](i∈k)\), 更新\(dis[k+1]=min(dis[k+1], y[falg])\)
最後輸出\(ans/2\)。
程式碼
#include <cmath> #include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int MAXN = 6005; const int MAXM = 1e6 + 5; int n, m, k; double x[MAXN], y[MAXN], dis[MAXN], ans; bool vis[MAXN]; double Dist(int u, int v) { return sqrt((x[u] - x[v]) * (x[u] - x[v]) + (y[u] - y[v]) * (y[u] - y[v])); } int main() { scanf ("%d %d %d", &n, &m, &k); for (int i = 1; i <= k; i++) { scanf ("%lf %lf", &x[i], &y[i]); dis[i] = (m * 1.0) - y[i]; } dis[k + 1] = m; dis[0] = INF; ans = -1; while (1) { int flag = 0; for (int i = 1; i <= k + 1; i++) { if (vis[i] == 0 && dis[i] < dis[flag]) flag = i; } vis[flag] = 1; ans = max(ans, dis[flag]); if (flag == k + 1) break; for (int i = 1; i <= k; i++) { dis[i] = min(dis[i], Dist(i, flag)); } dis[k + 1] = min(dis[k + 1], y[flag]); } printf ("%.9lf", ans / 2); return 0; }