BZOJ2458 Beijing2011最小三角形(分治)
类似于平面最近点对,考虑分治,即分别计算分割线两侧的最小三角形再考虑跨过线的三角形。
复杂度证明也是类似的,对于某一个点,在另一侧可能与其构成最小三角形的点在一个d*d/2的矩形内(两边之和大于第三边),并且这些点所组成的三角形周长均不小于d。然而并不清楚这里至多会有多少个点,vfk曾说上界是16,我当然不会证明这个上界也构造不出来有这么多点的方案。找这些点的时候归并就可以做到线性。那么复杂度是O(nlogn)乘上枚举这些点的常数2*16*15/2,看起来根本跑不动不过这个上界肯定是特别松的所以一点也不虚。
算距离的时候会爆int。以及luogu数据疑似有锅。
#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f; } #define N 200010 #define inf 1000000000 int n; double ans=inf; struct data { int x,y; bool operator <(const data&a) const { return x<a.x||x==a.x&&y<a.y; } double operator -(const data&a) const { return sqrt(1ll*(x-a.x)*(x-a.x)+1ll*(y-a.y)*(y-a.y)); } }a[N],b[N],c[N]; void getans(data *b,data *c,int n,int m) { int s=1,t=0; for (int i=1;i<=n;i++) { while (s<=m&&c[s].y+ans/2<b[i].y) s++; while (t<m&&c[t+1].y-ans/2<b[i].y) t++; for (int j=s;j<t;j++) { double tot=b[i]-c[j]; for (int k=j+1;k<=t;k++) ans=min(ans,tot+(c[k]-b[i])+(c[k]-c[j])); } } } void solve(int l,int r) { if (l==r) return; int mid=l+r>>1; solve(l,mid); solve(mid+1,r); int n=0,m=0,MID=-inf; for (int i=l;i<=mid;i++) MID=max(MID,a[i].x); for (int i=l;i<=mid;i++) if (2*(MID-a[i].x)<ans) b[++n]=a[i]; for (int i=mid+1;i<=r;i++) if (2*(a[i].x-MID)<ans) c[++m]=a[i]; getans(b,c,n,m); getans(c,b,m,n); int i=l,j=mid+1; for (int k=l;k<=r;k++) if (j>r||i<=mid&&a[i].y<a[j].y) b[k]=a[i++]; else b[k]=a[j++]; for (int k=l;k<=r;k++) a[k]=b[k]; } int main() { #ifndef ONLINE_JUDGE freopen("bzoj2458.in","r",stdin); freopen("bzoj2458.out","w",stdout); const char LL[]="%I64d\n"; #else const char LL[]="%lld\n"; #endif n=read(); for (int i=1;i<=n;i++) a[i].x=read(),a[i].y=read(); sort(a+1,a+n+1); solve(1,n); printf("%.6lf",ans); return 0; }
分类:
分治
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· Vite CVE-2025-30208 安全漏洞
· 《HelloGitHub》第 108 期
· MQ 如何保证数据一致性?
· 一个基于 .NET 开源免费的异地组网和内网穿透工具