kd树解平面最近点对
早上起来头有点疼,突然就想到能不能用kd树解平面最近点对问题,就找了道题试了一下,结果可以,虽然效率不高,但还是AC了~
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007
题目要求平面上最近点对间距离的一半。
思路如下:先建立一棵树,所有点插入树中,之后为每个点查询其最近点,枚举找到最小值。注意查询的时候不要让点自己跟自己比。个人感觉,这种写法也可以达到O(nlogn)的复杂度。建树分区间的时候,按x,y中跨度大的一个来分,应该就接近O(nlogn)了,不过我太懒了,那种方法之后再试,现在先x,y轮流着来了。
kd树代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cmath>
#define MAX (101000)
#define pow(x) ((x)*(x)) using namespace std; int n, idx; struct Point{
double x[];
bool operator < (const Point &u) const{
return x[idx] < u.x[idx];
}
}po[MAX]; struct Tree {
Point p[MAX<<];
int son[MAX<<];
bool f[MAX<<];
int ps[MAX<<];
void build ( int l , int r , int u = , int dep = )
{
if(l > r) return;
son[u] = r-l;
son[u<<] = son[u<<|] = -;
idx = dep%;
int mid = (l+r)>>;
nth_element(po+l, po+mid, po+r+);
p[u] = po[mid], ps[u] = mid;
build ( l , mid- , u<< , dep+ );
build ( mid+ , r , u<<| , dep+ );
} double query(Point a, int id, int u = , int dep = ){
if(son[u] == -) return 1000000000.0; double dis = pow(p[u].x[]-a.x[]) + pow(p[u].x[]-a.x[]);
if(ps[u] == id) dis = 1000000000.0;
int dim = dep%, fg = ;
int x = u<<, y = u<<|;
if(a.x[dim] >= p[u].x[dim]) swap(x, y);
double tm1 = 1000000000.0, tm2 = 1000000000.0;
if(~son[x])tm1 = query(a, id, x, dep+);
if(pow(a.x[dim] - p[u].x[dim]) < tm1) fg = ;
if(~son[y] && fg) tm2 = query(a, id, y, dep+);
if(dis > tm1) dis = tm1;
if(dis > tm2) dis = tm2;
return dis;
}
}kd; int main(){
while(~scanf("%d", &n), n){
for(int i = ; i < n; i++)
scanf("%lf %lf", &po[i].x[], &po[i].x[]);
memset(kd.f, , sizeof(kd.f));
memset(kd.ps, -, sizeof(kd.ps));
kd.build(, n-);
double ans = 1000000000.0;
for(int i = ; i < n; i++){
double tm = kd.query(po[i], i);
if(tm < ans) ans = tm;
}
printf("%.2lf\n", sqrt(ans)/);
}
return ;
}
kd树解平面最近点对的更多相关文章
- C# 通过KD树进行距离最近点的查找.
本文首先介绍Kd-Tree的构造方法,然后介绍Kd-Tree的搜索流程及代码实现,最后给出本人利用C#语言实现的二维KD树代码.这也是我自己动手实现的第一个树形的数据结构.理解上难免会有偏差,敬请各位 ...
- BZOJ - 2648 KD树 最近点查询
省赛后躺尸几天又回来更新了,内容是说好的KD树.. 具体操作从代码中感受一下 感觉已经把KD树尽量封装好了(虽然全局的D看着极不顺眼) 需要注意的是估值函数的判断条件 #include<bits ...
- K-D树详解
K-D树最近邻算法https://blog.csdn.net/image_fzx/article/details/80624968 一般说来,索引结构中相似性查询有两种基本的方式: 一种是范围查询,范 ...
- KNN算法与Kd树
最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知 ...
- k临近法的实现:kd树
# coding:utf-8 import numpy as np import matplotlib.pyplot as plt T = [[2, 3], [5, 4], [9, 6], [4, 7 ...
- tju_4147 kd树+最小生成树
kd树模板+全图最小生成树 标签(空格分隔): kd树+最小生成树 题目链接 题意: k维太空中有n个点,每个点可以与距离它m近的点连边,现在给你一堆点,并给出坐标,现在要建立通信网络,一些可以互相到 ...
- 02-17 kd树
目录 kd树 一.kd树学习目标 二.kd树引入 三.kd树详解 3.1 构造kd树 3.1.1 示例 3.2 kd树搜索 3.2.1 示例 四.kd树流程 4.1 输入 4.2 输出 4.3 流程 ...
- 从K近邻算法谈到KD树、SIFT+BBF算法
转自 http://blog.csdn.net/v_july_v/article/details/8203674 ,感谢july的辛勤劳动 前言 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章 ...
- <转>从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
转自 http://blog.csdn.net/likika2012/article/details/39619687 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经 ...
随机推荐
- 20180826(01)-Java数据结构
Java 数据结构 Java工具包提供了强大的数据结构.在Java中的数据结构主要包括以下几种接口和类: 枚举 (Enumeration) 位集合(BitSet) 向量 (Vector) 栈 (Sta ...
- Linux 系统下文件夹与文件的读写可执行权限问题
linux是一个多用户操作系统,linux对文件系统内的所有文件,实行了严格的权限划分管理.防止没有权限的用户访问某个文件.linux文件或目录的权限分为 读.写.可执行三种权限.文件访问的用户类别分 ...
- Swap——hdu 2819
Swap Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- scrapy中的cookies参数详解
COOKIES_ENABLED 默认: True 是否启用cookiesmiddleware.如果关闭,cookies将不会发送给web server. COOKIES_DEBUG 默认: False ...
- linux 执行shell文件
执行的时候总是报错 安装软件: yum install dos2unix chmod +x test.sh dos2unix test.sh 这样执行sh文件不会报一下异常,主要是因为windows中 ...
- Eclipse总是自动跳到ThreadPoolExecutor
出现这种状况是因为Eclipse默认开启挂起未捕获的异常(Suspend execution on uncaught exceptions),只要关闭此项就可以了.解决方法:在eclipse中选择Wi ...
- jmeter之ServerAgent监控资源
对linux服务器的服务进行压测时,服务器的运行情况可以通过添加插件来观察,而不用使用top命令实时的去看 1.资源准备 2.环境准备 3.资源监控 1.资源准备 可通过该网址下载jmeter所有插件 ...
- python实现堆栈与队列的方法
python实现堆栈与队列的方法 本文实例讲述了python实现堆栈与队列的方法.分享给大家供大家参考.具体分析如下: 1.python实现堆栈,可先将Stack类写入文件stack.py,在其它程序 ...
- 2019/11/02 TZOJ
1001 ShaoLin http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=6003 标记一下i ...
- 回调-> 观察者模式->反应堆模式
关于回调: 回调是观察者模式以及反应堆模式的基础 一句话,回调就是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调.“If you call me, i will ca ...