【题解】Star Way To Heaven
题目大意
小
伤心的走上了 Star way to heaven。
到天堂的道路是一个笛卡尔坐标系上一个的长方形通道(顶点在( , )和( , ))。
小从最左边任意一点进入,从右边任意一点走到天堂,最左最右的距离为 ,上下边界距离为 。
其中长方形有个 ,每个 都有一个整点坐标, 的大小可以忽略不计。
每个以及长方形上下两个边缘宇宙的边界都有引力,所以为了成功到达 小 离他们越远越好。
请问小走到终点的路径上,距离所有星星以及边界的最小距离最大值可以为多少?
输入格式
一行三个整数
, , 。
接下来行,每行两个整数 , 表示一个点的坐标。
输出格式
一行一个数表示答案。保留到小数点后9位。
样例
样例输入
10 5 2
1 1
2 3样例输出
1.118033989
Solution
首先,我们如果要从两个Star之间穿过,那么选择从它们的中点穿过一定不劣,所以我们的问题就转化为了找从左边到右边所有路径中所要穿过的Star中离的最近的两个的最大值,这个东西类似于[NOIP模拟测试]:water(BFS)这道题,但是当时我是使用BFS直接A掉的,其实正解就是最小生成树,那么这道题我们也用最小生成树。
怎么利用最小生成树呢?
首先是建图,先将所有的
然后我们考虑怎么利用最小生成树,我们要从左边到右边,也就要穿过在最小生成树中从上边界到下边界最短路径中的一条边,而最优策略一定是走最长的那一条边,所以整道题便转化为了找最小生成树中从上边界到下边界的最短路径中的最长边,答案极为这条边边长的一半。
但是我们这里需要注意的是空间问题,显然Kruskal算法在稠密图中的空间复杂度高的可怕,而这道题考的我们便是对Prim算法的利用,所以有的不常用的算法至少还是要知道其原理的。
Code
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
const int MAXN = 6005, INF = 1e9;
int n, m, k;
double x[MAXN], y[MAXN], dis[MAXN], ans;
bool vis[MAXN];
double Dis(int i, int j) {
return sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
}
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 - y[i];
}
k++;
dis[k] = m;
while (1) {
int p = -1;
for (int i = 1; i <= k; i++)
if (!vis[i] && (p == -1 || dis[i] < dis[p]))
p = i;
if (p == -1)
continue;
vis[p] = 1;
ans = max(ans, dis[p]);
if (p == k)
break;
for (int i = 1; i < k; i++)
dis[i] = min(dis[i], Dis(i, p));
dis[k] = min(dis[k], y[p]);
}
printf("%.9lf", ans * 0.5);
return 0;
}
本文来自博客园,作者:zhou_ziyi,转载请注明原文链接:https://www.cnblogs.com/zhouziyi/p/16556819.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具