说实话,最初看到题目中说的“可以向任意方向移动”吓了一跳,脑中脑补了各种行走的蜿蜒曲径。。。

在一不小心点开标签后才发现,其实只是一个坑点在误导读者。

题目大意

最短路定义为经过的未被覆盖区域,给定起点和终点,求最短路

思路

问题1:最短路跑什么?

首先我们要想清楚一件非常重要的性质,题目中给定的最短路只有一个条件:经过的未被覆盖的路径;

也就是说,为了尽可能的减少暴露的路径的长度,不论覆盖区域中的路径长度有多长,都要走这条路(所以据说输出0都可以得到35分的好成绩)

问题2:最短路怎么跑?

解决完问题1后,第二个问题迎面而来:最短路怎么跑?

相信一定有不少人这时脑中也脑补了各种弯曲的路线,但我们转念一想:

以下这种情况,哪条路径更优?(蓝色or绿色)

无法判断的话,可以这么理解:

我们以start为圆心,第一段蓝色线段暴露的路径为半径画圆,与黑色的圆相切与A点;

那么第一段蓝色线段一定垂直于切线,而绿色线段与切线有一定的夹角;

所以第一段蓝色线段暴露的路径长度比绿色线段短;

同理,第二段蓝色线段暴露的路径长度也比绿色线段短,所以蓝色路比绿色路优。

至此,我们得到了一条重要的结论:对于一个覆盖的区域来说,经过它的圆心永远比不经过圆心优

问题3:怎样转化成最短路?

其实题目隐藏了一条重要信息:起点和终点也有覆盖范围,只不过是0

那么我们就可以把所有点都归成一类:

struct node{int x,y,len;}a[N];//坐标及半径

瞄一眼数据范围: n ≤ 1000 n\le1000 n≤1000

这么小?直接点之间两两连边!

  1. 点的编号?就是读入顺序,起点和终点另外加两个。

  2. 边权?两个点之间的欧几里得距离减去两个点覆盖区域的半径。

  3. 怎么跑?dij或spfa皆可,裸的最短路板子。

代码

#include<bits/stdc++.h>
#define N 1005//点数
#define M 1000005//边数
#define inf 0x3f3f3f3f3f3f3f3f//inf开大一点,数据范围是1e9
#define endl '\n'
#define debug cerr<<__LINE__<<endl
using namespace std;
int n,m;
int xs,xt,ys,yt;
inline int read(){register int f=1,k=0;register char c=getchar();while(c!='-'&&(c<'0'||c>'9')) c=getchar();if(c=='-') f=-1,c=getchar();while(c>='0'&&c<='9') k=(k<<3)+(k<<1)+(c^48),c=getchar();return f*k;
}
inline void write(register int x){if(x<0) x=-x,putchar('-');if(x>9) write(x/10);putchar(x%10+'0');
}
inline long long mul(const register int x){return 1ll*x*x;}//一定要记得开long long
inline double get_dis(int x,int y,int a,int b){return sqrt(mul(a-x)+mul(b-y));}//欧几里得距离
namespace first{//特判了一下前20%数据int xx,yy,len;inline double solve(){xx=read(),yy=read(),len=read();return min(get_dis(xs,ys,xt,yt),get_dis(xx,yy,xs,ys)+get_dis(xt,yt,xx,yy)-(len<<1));}
}
namespace second{int head[N],cnt;double dis[N];//欧几里得距离,用doublebool vis[N];struct edge{int to,nxt;double val;}e[M<<1];//同上,doublestruct node{int x,y,len;}a[N];priority_queue<pair<double,int>,vector<pair<double,int> >,greater<pair<double,int> > >q;inline void add(register int u,register int v,register double w){e[++cnt].to=v;e[cnt].val=w;e[cnt].nxt=head[u];head[u]=cnt;e[++cnt].to=u;e[cnt].val=w;e[cnt].nxt=head[v];head[v]=cnt;}inline void dijkstra(const register int s){fill(dis+1,dis+n+3,inf);//因为是double类型,所以不能用memset,fill是比for循环更好的选择dis[s]=0;q.emplace(0,s);//即q.push(make_pair(0,s));while(!q.empty()){//裸的最短路板子const register int u=q.top().second;q.pop();if(!vis[u]){vis[u]=1;for(register int i=head[u];i;i=e[i].nxt){const register int v=e[i].to;if(dis[v]>dis[u]+e[i].val){dis[v]=dis[u]+e[i].val;q.emplace(dis[v],v);}}}}}inline double solve(){for(register int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(),a[i].len=read();a[n+1]=(node){xs,ys,0};a[n+2]=(node){xt,yt,0};//额外把起点和终点都当成覆盖区域for(register int i=1;i<=n+2;i++)for(register int j=i+1;j<=n+2;j++) add(i,j,max(0.0,get_dis(a[i].x,a[i].y,a[j].x,a[j].y)-a[i].len-a[j].len));//注意这里要特判dis,如果dis<0就说明两个圆有交集,边权直接赋为0dijkstra(n+1);return dis[n+2];}
}
main(void){freopen("1.in","r",stdin);xs=read(),ys=read();xt=read(),yt=read();n=read();if(n==1) return printf("%.10lf\n",first::solve()),0;//前20%数据return printf("%.10lf\n",second::solve()),0;//后80%数据return 0;
}

码风较奇葩(压行强迫症+卡常小能手)

欢迎觉得做法很麻烦或有错误的巨佬来喷

[ARC064C] Cosmic Rays-宇宙射线 题解相关推荐

  1. Cosmic Rays

    6487: Cosmic Rays 时间限制: 1 Sec   内存限制: 128 MB 提交: 76   解决: 37 [ 提交][ 状态][ 讨论版][命题人: admin] 题目描述 On th ...

  2. Cosmic Rays(dijsktra)

    6487: Cosmic Rays 时间限制: 1 Sec  内存限制: 128 MB 题目描述 On the xy-plane, Snuke is going to travel from the ...

  3. Cosmic Rays(最短路变形)

    Cosmic Rays 时间限制: 1 Sec  内存限制: 128 MB 题目描述 On the xy-plane, Snuke is going to travel from the point ...

  4. 你知道cosmic吗

    是的,我知道."cosmic" 有多个意思,它可以指宇宙的,也可以指非常高尚或神圣的.例如,"cosmic rays" 指的是宇宙中的射线,而 "co ...

  5. 时隔16年,Science再次发布“全世界最前沿的125个科学问题”!

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 <科学>杂志曾于创刊125周年之际发布过125个推动基础 ...

  6. 我们生活在一个虚拟世界的概率有多大?

    © Thomas Leuthard - Flickr 来源:人工智能AI技术 利维坦按: 我们在以前的文章中介绍过约翰·惠勒提出的延迟实验: 第一步: 我们拿一块经过半镀银处理的反射镜BS1来代替双缝 ...

  7. 新版:全世界最前沿的125科学问题

    "我们可以生活在一个去化石燃料的世界中吗?""意识存在于何处?""为什么时间似乎只朝一个方向流动?"--今天(4月10日)下午,上海交通大学 ...

  8. 电磁场与电磁波_您的大脑在电磁场上

    电磁场与电磁波 We all simultaneously occupy the space above a giant celestial generator. In its outer core, ...

  9. 非侵入性脑刺激和太空探索

    美国国家航空航天局NASA正在准备针对月球和火星进行更长时间的太空任务,由于银河宇宙辐射.非自然重力场和极端环境对生命带来的威胁,宇航员的健康和表现正成为一个核心问题.在太空中,人脑经历了与液体漂移和 ...

最新文章

  1. Hash函数的安全性
  2. [Kerberos] Java client访问kerberos-secured cluster
  3. wincc 服务器共享文件夹,wincc共享文件夹Simatic Shell中项目的互连是什么意思-工业支持中心-西门子中国...
  4. 7-5 编程题:选修课成绩统计问题-hebust (12 分)
  5. 监督学习 | 集成学习 之Bagging、随机森林及Sklearn实现
  6. catkin_make
  7. Linux内存管理 brk(),mmap()系统调用源码分析1:基础部分
  8. 9-51单片机ESP8266学习-AT指令(测试TCP服务器--51单片机程序配置8266,C#TCP客户端发信息给单片机控制小灯的亮灭)...
  9. matlab 2017a安装教程
  10. Xcode9安装插件,xcode9安装使用Alcatraz
  11. mysql 统计新增用户_Mysql 查询:统计某月每日新增用户在新增当天的充值笔数、当天新增用户充值的总人数和充值总金额...
  12. 会使您势不可挡的程序员的行为
  13. JDK1.8新特性及常用新特性
  14. js页面中实现加载更多功能
  15. 手机比较版本差异工具
  16. 深度学习 Deeplab语义分割
  17. 【STM32F4系列】【HAL库】【自制库】WS2812(软件部分)(PWM+DMA)
  18. 三轴加速度计得到角度值原理
  19. 高通狂吹新GPU:赶超桌面显卡
  20. 我国成功发射第七颗北斗导航卫星

热门文章

  1. 奶白现代简约风格装修
  2. text-indent 的特殊性?
  3. java zlib 解压_在javascript中解压缩gzip和zlib字符串
  4. 仅作笔记用:Windows 11 通过 VBS 打开 IE 浏览器
  5. 试用STC 32位单片机 老梁开源示波器
  6. 现在运动耳机哪个好、目前市面上最适合跑步用的耳机排名清单
  7. linux basename用法,Linux basename命令的使用详解
  8. 缺陷检查需要了解的记录
  9. 耐人寻味的Temp文件(三)
  10. 使用PYTHON将上百个TXT文件提取其中信息生成一个csv