VJ传送门

简要题意:给出两个大小均为\(N\)的点集\(A,B\),试在\(A\)中选择一个点,在\(B\)中选择一个点,使得它们在所有可能的选择方案中欧几里得距离最小,求出这个距离


下面给出的两种解法基本上都能够被卡成\(O(n^2)\)……

按照平面最近点对的做法去做,只是在贡献答案的时候加上所属点集不同的限制就可以了。

当然这个可以卡,只要把\(A\)、\(B\)集合之间分得很开,而\(A\)集合和\(B\)集合内部的点两两之间的距离很小,这样在分治下去的过程中没法贡献答案,最后在分治的第一层就有可能会退化成\(O(n^2)\)

如果你愿意可以旋转坐标系来部分解决上面的问题

代码没有写

K-D Tree

把\(A\)集合的点全部加进去构建K-D Tree,对于\(B\)集合内的每个点在K-D Tree上搜索,加个最优化剪枝。

这个怎么卡应该不需要说了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
#define ld long double
#define int long long
//This code is written by Itst
using namespace std;inline int read(){int a = 0;char c = getchar();bool f = 0;while(!isdigit(c) && c != EOF){if(c == '-')f = 1;c = getchar();}if(c == EOF)exit(0);while(isdigit(c)){a = a * 10 + c - 48;c = getchar();}return f ? -a : a;
}const int MAXN = 1e5 + 7;
struct point{int x , y , ind;point(int _x = 0 , int _y = 0 , int _i = 0):x(_x) , y(_y) , ind(_i){}
}P[MAXN];
int N , rt;
int ch[MAXN][2] , X[MAXN][2] , Y[MAXN][2] , p[MAXN][2];
ld ans;bool cmp1(point a , point b){return a.x == b.x ? a.y < b.y : a.x < b.x;
}bool cmp2(point a , point b){return a.y == b.y ? a.x < b.x : a.y < b.y;
}inline ld calc(point a , point b){return sqrt((long double)(a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}inline void merge(int x , int y){X[x][0] = min(X[x][0] , X[y][0]);X[x][1] = max(X[x][1] , X[y][1]);Y[x][0] = min(Y[x][0] , Y[y][0]);Y[x][1] = max(Y[x][1] , Y[y][1]);
}int build(int l , int r , bool f){if(l > r)return 0;int mid = (l + r) >> 1;nth_element(P + l , P + mid , P + r + 1 , f ? cmp1 : cmp2);int t = P[mid].ind;X[t][0] = X[t][1] = P[mid].x;Y[t][0] = Y[t][1] = P[mid].y;if(ch[t][0] = build(l , mid - 1 , f ^ 1))merge(t , ch[t][0]);if(ch[t][1] = build(mid + 1 , r , f ^ 1))merge(t , ch[t][1]);return t;
}inline ld qw(int x , point p){int mx = max(max(X[x][0] - p.x , p.x - X[x][1]) , 0ll) , my = max(max(Y[x][0] - p.y , p.y - Y[x][1]) , 0ll);return sqrt((long double)mx * mx + my * my);
}void dfs(int x , point q , bool f){if(x == 0 || qw(x , q) > ans)return;ans = min(ans , calc(point(p[x][0] , p[x][1]) , q));if(f ? cmp1(point(p[x][0] , p[x][1]) , q) : cmp2(point(p[x][0] , p[x][1]) , q)){dfs(ch[x][1] , q , f ^ 1);dfs(ch[x][0] , q , f ^ 1);}else{dfs(ch[x][0] , q , f ^ 1);dfs(ch[x][1] , q , f ^ 1);}
}signed main(){
#ifndef ONLINE_JUDGEfreopen("in","r",stdin);freopen("out","w",stdout);
#endiffor(int T = read() ; T ; --T){N = read();for(int i = 1 ; i <= N ; ++i){P[i].x = p[i][0] = read();P[i].y = p[i][1] = read();P[i].ind = i;}rt = build(1 , N , 0);ans = 1e50;for(int i = 1 ; i <= N ; ++i){P[0].x = read();P[0].y = read();dfs(rt , P[0] , 0);}cout << fixed << setprecision(3) << ans << endl;}return 0;
}

转载于:https://www.cnblogs.com/Itst/p/10325668.html

POJ3714 Raid 分治/K-D Tree相关推荐

  1. 点分治问题 ----------- HDU6881 Tree Cutting or 2020杭电多校第10场 [点分治+思维]

    题目链接 题目大意: 给定nnn个节点的树,问删除尽可能小的点使得树的直径不超过KKK,输出最小删除的点数,(1<=k<=n<=3e5)(1<=k<=n<=3e5) ...

  2. ICPC 南昌现场赛 K:Tree(dsu on tree + 动态开点线段树)

    Tree 让我们找满足一下五个条件的(x,y(x, y(x,y)点对有多少: x≠yx \neq yx​=y xxx不是yyy的祖先 yyy不是xxx的祖先 dis(x,y)≤kdis(x, y)\ ...

  3. (nlogn)的时间复杂度求 最近点对 hdu 1007 凹凸曼与小怪兽的故事 poj3714 Raid...

    hdu 1007  Quoit Design http://acm.hdu.edu.cn/showproblem.php?pid=1007 zoj 2107 Quoit Design http://a ...

  4. POJ3714 Raid 平面最近点对

    利用分治来求平面最近点对 只需要查后面6个点就好了 原因在于https://blog.csdn.net/liufeng_king/article/details/8484284 两个集合的话就把不同集 ...

  5. KD tree (K dimensional tree)多维空间搜索 近邻

    kd树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索).

  6. 洛谷 - P4390 [BOI2007]Mokia 摩基亚(带修二维数点-四叉线段树/CDQ分治)

    题目链接:点击查看 题目大意:给出一个二维平面坐标系,需要执行数次操作,具体操作分为下列两种: 1 x y a:坐标 (x,y)(x,y)(x,y) 加上 aaa 个点 2 x1 y1 x2 y2:查 ...

  7. CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)

    题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...

  8. 牛客多校3 - Sort the Strings Revision(笛卡尔树+分治)

    题目链接:点击查看 题目大意:给出一个长度为 n 的数字串 s[ 0 ],每个位置的赋值初始时为 s[ i ] = i % 10 ( i ∈ [ 0 , n - 1 ] ),现在有一个长度为 n 的排 ...

  9. 牛客多校8 - All-Star Game(线段树分治+并查集按秩合并的撤销操作)

    题目链接:点击查看 题目大意:有 n 个球员和 m 个球迷,一个球员可能是多个球迷的粉丝,需要选择最少的球员进行比赛,使得所有的球迷都愿意观看(对于每个球迷来说,都有至少一个其喜欢的球员入选比赛) 对 ...

最新文章

  1. 企业做SEO优化哪些行为会被判定为作弊?
  2. python学习笔记 day15 内置函数(三)
  3. cnblogs url temp
  4. MySQL查看、创建和删除索引的方法
  5. MySQL导出表结构相关字段以及把字段由下划线转驼峰命名
  6. java xml dom getelementbyid,DOM中常见的元素获取方式
  7. DataFrame不同风格比较
  8. python搭建selenium_自动化测试之路3-selenium3+python3环境搭建
  9. Flutter——限制TextField只能输入汉字或英文字母或数字,并限制输入最多中文10字符,英文20字符
  10. iar c语言单片机指针,51单片机IAR编程示例
  11. 夜间灯光数据dn值_一种基于遥感夜间灯光数据和能源消耗统计数据的城市能耗量空间化方法与流程...
  12. qq互联android sdk,QQ互联API列表 - YangJunwei
  13. 最新版:移动设备管理与OMA DM协议 V6
  14. 小赛毛游C记——初始C语言(4)
  15. TRUNCATE,DORP,DELETE
  16. 求导,微分,积分的区别
  17. 【完美解决】org.apache.catalina.core.StandardContext.filterStart 启动过滤器异常
  18. BZOJ1002 FJOI2007 轮状病毒 【基尔霍夫矩阵+高精度】
  19. 无法达成目标的五个关键因素
  20. 【Arduino】mega2560 驱动grove 三色水墨屏

热门文章

  1. javascript自制函数图像生成器
  2. 2018中国域名大会-强调服务与网络信息安全
  3. 03-dotnet core创建区域[Areas]及后台搭建
  4. hadoop-0.20.2完全分布式集群
  5. partial、struct、interface与C#和CLR的关系
  6. 做个插件MaterialSpinner笔记
  7. 英语学习—每天进步一丢丢系列(一)
  8. mac php5.6 gd 扩展,mac 编译安装php5.6.40
  9. 有多少人乘坐公交车时用NFC付钱?
  10. 怎么windows升级?windows版本升级?