分治求平面最近点对.
给出平面上的 $n$ 个点,询问不同的两个点之间距离最小是多少.
暴力
直接枚举两个点计算距离,时间复杂度 $O(n^2)$ .
kd 树
建出 kd 树,对每个点询问一下与它最近的距离.
适当剪枝,复杂度为玄学.
分治
把所有点按照 $x$ 排序,从中间划分成左右两部分,递归计算两部分内部各自的贡献,再考虑跨过中线的贡献.
记 $d$ 表示左右两部分内部贡献的最小值,那么计算跨过中线的点对时,只需要考虑距离 $<d$ 的点对.
假定中线为 $l:x=k$ ,那么只用考虑横坐标在区间 $(x-k,x+k)$ 内的点.
把这些点拿出来按照 $y$ 排序,枚举起点,向后找终点,当两者纵坐标之差达到 $k$ 时就换下一个起点.
可以证明 ,对于每个起点,有效的终点不会超过 $6$ 个.
时间复杂度 $T(n)=2T(\frac n 2) + O(n\log n)=O(n\log^2 n)$ .
模板题
给出平面上 $n$ 个点,需要找出一个圆,使得它恰好包含了其中的一个点,求出这个圆可能的最大半径.
以最近点对为直径的两个端点作圆,将它做微小偏移即可得到所求的圆,半径可以直接视作最近点对距离的一半.
1 | //%std |