BZOJ 2458 最小三角形

题面

一个平面上有很多点,求他们中的点组成的周长最小的三角形的周长。

题解

平面最近点对差不多,也是先把区间内的点按x坐标从中间分开,递归处理,然后再处理横跨中线的三角形。

如何缩小范围?设左右两个子区间发现的最小周长是d,则与中线距离超过d / 2都没有用了,对于一个点,所有与它距离超过d / 2的点也都没有用。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 200005;
int n;
struct point {
double x, y;
bool operator < (const point &b) const{
return x < b.x;
}
point operator - (const point &b){
return (point){x - b.x, y - b.y};
}
double norm(){
return sqrt(x * x + y * y);
}
} p[N], a[N], b[N], c[N]; double calc(point x, point y, point z){
return (x - y).norm() + (y - z).norm() + (z - x).norm();
}
double solve(int l, int r){
if(l == r) return 1e20;
int mid = (l + r) >> 1;
double xmid = (p[mid].x + p[mid + 1].x) / 2;
double d = min(solve(l, mid), solve(mid + 1, r));
int pos = l, pb = 0, pc = 0, pl = l, pr = mid + 1;
while(pos <= r)
if(pl <= mid && (pr > r || p[pl].y < p[pr].y)){
if(p[pl].x > xmid - d / 2) b[++pb] = p[pl];
a[pos++] = p[pl++];
}
else{
if(p[pr].x < xmid + d / 2) c[++pc] = p[pr];
a[pos++] = p[pr++];
}
for(int i = l; i <= r; i++)
p[i] = a[i];
if(l + 1 == r) return 1e20;
for(int i = 1, j = 1; i <= pb; i++){
while(j <= pc && b[i].y - c[j].y > d / 2) j++;
for(int k = j; k <= pc && abs(b[i].y - c[k].y) < d / 2; k++)
for(int h = k + 1; h <= pc && abs(b[i].y - c[h].y) < d / 2; h++)
d = min(d, calc(b[i], c[k], c[h]));
}
for(int i = 1, j = 1; i <= pc; i++){
while(j <= pb && c[i].y - b[j].y > d / 2) j++;
for(int k = j; k <= pb && abs(c[i].y - b[k].y) < d / 2; k++)
for(int h = k + 1; h <= pb && abs(c[i].y - b[h].y) < d / 2; h++)
d = min(d, calc(c[i], b[k], b[h]));
}
return d;
}
int main(){
read(n);
for(int i = 1; i <= n; i++)
scanf("%lf%lf", &p[i].x, &p[i].y);
sort(p + 1, p + n + 1);
printf("%.6lf\n", solve(1, n));
return 0;
}

BZOJ 2458 最小三角形 | 平面分治的更多相关文章

  1. BZOJ 2458: [BeiJing2011]最小三角形 | 平面分治

    题目: 给出若干个点 求三个点构成的周长最小的三角形的周长(我们认为共线的三点也算三角形) 题解: 可以参考平面最近点对的做法 只不过合并的时候改成枚举三个点更新周长最小值,其他的和最近点对大同小异 ...

  2. 【BZOJ 2458 最小三角形】

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1551  Solved: 549[Submit][Status][Discuss] Descripti ...

  3. bzoj-2458 2458: [BeiJing2011]最小三角形(计算几何+分治)

    题目链接: 2458: [BeiJing2011]最小三角形 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1101  Solved: 380 Des ...

  4. BZOJ2458 Beijing2011最小三角形(分治)

    类似于平面最近点对,考虑分治,即分别计算分割线两侧的最小三角形再考虑跨过线的三角形. 复杂度证明也是类似的,对于某一个点,在另一侧可能与其构成最小三角形的点在一个d*d/2的矩形内(两边之和大于第三边 ...

  5. [BJWC2011]最小三角形(分治+最近点对)

    题面:BJWC2011 最小三角形 \(solution:\) 昨天才学完平面最近点对,今天就要求平面最近的三个点,显然不是巧合. 仔细一思考,我们用来求平面最近点对的方法不就可以用到三个点上吗? 就 ...

  6. bzoj2458: [BeiJing2011]最小三角形(分治+几何)

    题目链接:bzoj2458: [BeiJing2011]最小三角形 学习推荐博客:分治法编程问题之最接近点对问题的算法分析 题解:先将所有点按x值排列,然后每次将当前区间[l,r]分成左右两半递归求解 ...

  7. Luogu4423 BJWC2011 最小三角形 平面最近点对

    传送门 题意:给出$N$个点,求其中周长最小的三角形(共线的也计算在内).$N \leq 2 \times 10^5$ 这道题唤起了我对平面最近点对的依稀记忆 考虑平面最近点对的分治,将分界线两边的求 ...

  8. bzoj 2458: [BeiJing2011]最小三角形 题解

    [前言]话说好久没有写题解了.到暑假了反而忙.o(╯□╰)o [原题] 2458: [BeiJing2011]最小三角形 Time Limit: 10 Sec  Memory Limit: 128 M ...

  9. 分治 - 计算几何 - BZOJ2458,[BeiJing2011]最小三角形

    http://www.lydsy.com/JudgeOnline/problem.php?id=2458 [BeiJing2011]最小三角形 描述 Frisk现在遇到了一个有趣的问题. 平面上有N个 ...

随机推荐

  1. VGGnet——从TFrecords制作到网络训练

    作为一个小白中的小白,多折腾总是有好处的,看了入门书和往上一些教程,很多TF的教程都是从MNIST数据集入手教小白入TF的大门,都是直接import MNIST,然后直接构建网络,定义loss和opt ...

  2. idea_debug

    条件断点 快捷键 cmd + shift +f8 demo 表达式求值 注意,调试的时候,选中相应变量 alt + f8 demo set value (感觉会非常有用) 调试时直接改变变量的值,快捷 ...

  3. Extreme Learning Machine 翻译

    本文是作者这几天翻译的一篇经典的ELM文章,是第一稿,所以有很多错误以及不足之处. 另外由于此编辑器不支持MathType所以好多公式没有显示出来,原稿是word文档. 联系:250101249@qq ...

  4. 基于Linux-3.9.4内核增加简单的时间片轮转功能

    简单的时间片轮转多道程序内核代码 原创作品转载请注明出处https://github.com/mengning/linuxkernel/ 作者:sa18225465 一.安装 Linux-3.9.4 ...

  5. mongoose和mongodb的几篇文章 (ObjectId,ref)

    http://mongoosejs.com/docs/populate.html http://stackoverflow.com/questions/6578178/node-js-mongoose ...

  6. nginx之location(root/alias)

    location配置 1. 语法规则(按优先级) =        表示精确匹配,优先级最高 ^~      表示uri以某个常规字符串开头,用于匹配url路径(而且不对url做编码处理,例如请求/s ...

  7. 使用python实现用微信远程控制电脑

    首先,我们要先看看微信远程控制电脑的原理是什么呢? 我们可以利用Python的标准库控制本机电脑,然后要实现远程的话,我们可以把电子邮件作为远程控制的渠道,我们用Python自动登录邮箱检测邮件,当我 ...

  8. Servlet 3.0 对异步处理的支持

    Servlet 3.0 实现了对异步处理的支持 通过利用注解@WebServlet(urlPatterns="/AServlet" AysnsSupported=true) 让后n ...

  9. 校友聊NABCD需求分析

    校友聊 NABCD需求分析 N:内网用户流量不够使用 A:基于局域网进行通讯 B:通讯不花费外网流量 C:目前学校还没有使用 D:将软件放在校园网,可以下载使用

  10. Gogoing的NABCD

    特点之一:路线推荐 N  用户出行需要一个合理的路线计划 A 运用百度地图,还有根据自己的所想去的地方,推荐最省时间,最省钱的路线安排 B 方便用户出行,节约时间,节约金钱 C 对于旅行方面的App, ...