[二分][并查集] Jzoj P5904 刺客信条(AC)
题解
- 如果,换个思路想想,我们把可以相通的点合并,那么最后只用判断能否有一条路经过
- 然后二分一个长度,以每个点为圆心画圆,将不能联通的放在同一个并查集内
- 那么如果左边的墙和下面的墙在同一个并查集内的话,那么就是不可能过去的嘛
- 还有就是上和下,下和右,上和左某一组在同一个并查集内的话,就无法从(0,0)到(x,y),感性理解一下
代码
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 using namespace std; 5 const double eps=1e-4; 6 int n,fa[2010]; 7 double l,r,ans,a[2010],b[2010],x,y; 8 int getfather(int x) { return !fa[x]?x:fa[x]=getfather(fa[x]); } 9 double sqr(double x) { return x*x; } 10 void merge(int x,int y) 11 { 12 int u=getfather(x),v=getfather(y); 13 if (u!=v) fa[u]=v; 14 } 15 bool check(double d) 16 { 17 memset(fa,0,sizeof(fa)); 18 for (int i=1;i<=n;i++) 19 { 20 if (a[i]<=d) merge(i,n+1); 21 if (b[i]<=d) merge(i,n+2); 22 if (a[i]+d>=x) merge(i,n+3); 23 if (b[i]+d>=y) merge(i,n+4); 24 } 25 for (int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) if (sqr(a[i]-a[j])+sqr(b[i]-b[j])<=4*d*d) merge(i,j); 26 if (getfather(n+1)==getfather(n+2)) return false;if (getfather(n+1)==getfather(n+3)) return false; 27 if (getfather(n+2)==getfather(n+4)) return false;if (getfather(n+3)==getfather(n+4)) return false; 28 return true; 29 } 30 int main() 31 { 32 freopen("AC.in","r",stdin),freopen("AC.out","w",stdout); 33 scanf("%lf%lf%d",&x,&y,&n); 34 for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i],&b[i]); 35 l=0,r=1e6; 36 while (r-l>=eps) 37 { 38 double mid=(l+r)/2; 39 if (check(mid)) ans=mid,l=mid+eps; else r=mid; 40 } 41 printf("%.2lf",ans); 42 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· C# 13 中的新增功能实操
· Vue3封装支持Base64导出的电子签名组件
· 万字长文详解Text-to-SQL
· Ollama本地部署大模型总结
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(4)