cdq分治可以很好地處理平面點對間具有某種性質的值或數量,最近點對也不例外。
參考oi wiki
先對x排序,cdq返回點集內部最近點對的距離記為mindis。
考慮如何合併左右區間,對於處於點集a的點a和b的點b,顯然
∣ a.
x−b.
x∣
<=m
indi
s|a.x-b.x|<=mindis
∣a.x−b
.x∣<=m
indi
s設a,b屬於c,找到c後,對於點p,k屬於c,顯然也要滿足
∣ p.
y−k.
y∣
<=m
indi
s|p.y-k.y|<=mindis
∣p.y−k
.y∣<=m
indi
s可以證明,對於點p,c中滿足上述性質的點不會超過7個,因為
∣ p.
x−k.
x∣
<=m
indi
s|p.x-k.x|<=mindis
∣p.x−k
.x∣<=m
indi
s,∣p.y
−k.y
∣<=m
indi
s|p.y-k.y|<=mindis
∣p.y−k
.y∣<=m
indi
s,把區間分為2個正方形,正方形邊長為mindis,對於每個正方形,再分為4個小正方形,而且每個小正方形內部最多有1個點,因為如果有大於兩個點,那麼,存在點x,y,,使得
d is
(x,y
) rt(2 (min dis2 )2 ) ndis dis(x,y)di s(x, y)rt(2 (2mi ndis )2) ndis 也就是說,我們每次合併兩個點集,計算點x時,與點y的dist中,y與x屬於同乙個集合的個數最多為7個,即計算時無效的計算最多為7次。 所以,為了方便計算,我們將cdq後的點按y的大小歸併。 raid 給定兩個點集,計算點集之間的最小距離。 給每個點加個flag,flag相同的點為同乙個點集,距離為inf using namespace std; char buf[ 1<<20] ,*p1=buf, *p2=buf; #define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?eof:*p1++) #define tt templateinline tt bool read (t &x) while(47 58)x= (x<<3) +(x<<1) +(c^48) ,c=gc() ;if(f)x= -x;return1; }tt void print (t x) tt bool read (t&a,t&b) tt bool read (t&a,t&b,t&c) typedef long long ll; const ll maxn= 1e5+8; #define lowbit(x) (x&(-x)) struct pointpoint[maxn<<1] ,tmp[maxn<<1] ;double dis(point&a,point&b) bool cmp(point&a,point&b) int n; double cdq( int l, int r) }return mindis; }int main() sort (point+ 1,point+ 1+n* 2,cmp) ;printf ("%.3f\n" ,cdq(1 ,n<<1) );}return0; } 在與聯盟的戰鬥中屢戰屢敗後,帝國撤退到了最後乙個據點。依靠其強大的防禦系統,帝國擊退了聯盟的六波猛烈進攻。經過幾天的苦思冥想,聯盟將軍亞瑟終於注意到帝國防禦系統唯一的弱點就是能源 該系統由n個核電站 能源,其中任何乙個被摧毀都會使防禦系統失效。將軍派出了n個 進入據點之中,打算對能源站展開一次突襲。... 1 演算法描述 已知集合s中有n個點,一共可以組成n n 1 2對點對,蠻力法就是對這n n 1 2對點對逐對進行距離計算,通過迴圈求得點集中的最近點對 2 演算法時間複雜度 演算法一共要執行 n n 1 2次迴圈,因此演算法複雜度為o n2 實現 利用兩個for迴圈可實現所有點的配對,每次配對算出... 給定平面上n個點,找出其中的一對點的距離,使得在這n個點的所有點對中,該距離為所有點對中最小的 將每乙個點按照橫座標排序,然後分治區間 1,n 1,n 1,n 再內乙個遞迴函式內 如下 include using namespace std struct node a 300000 int temp...#include
平面最近點對問題 分治
平面最近點對問題 分治
演算法 分治 平面最近點對