POJ3714 Raid(最近點對問題 分治 )

2021-08-19 03:13:04 字數 1199 閱讀 3722

傳送門

題意就是尋找兩個集合中的點的最近點對。

kd-tree??我不會啊。。然後去膜大佬了

找最近點對的經典做法是分治,首先按照x座標排序,把一大塊分成左右兩塊,分別在左右兩塊裡找最近點對,但是如果這個點對橫跨兩塊的話他一定在(mid的橫座標-d)和(mid的橫座標+d)【d是當前找到的最近點對距離】之間要不然他一定不是最近的,然後暴力找即可,可以再按y座標排序優化複雜度。也許複雜度是o(

nlog

n)o (n

logn

)???

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=200010;

const

double inf=1e10;

struct point

p[maxn];

double dis(point a,point b)

bool cmp1(point a,point b)

else

if(r==l+2)//有三個點,分別判斷情況

else

return min(dis(p[l],p[l+1]),min(dis(p[l+1],p[l+2]),dis(p[l],p[l+2])));

}int mid=(l+r)/2;

double d=min(get(l,mid),get(mid+1,r));

int cnt=0;//找到兩個塊之間連線的點

for(int i=l;i<=r;i++) if(p[i].x>=p[mid].x-d && p[i].x<=p[mid].x+d) tmp[++cnt]=i;

sort(tmp+1,tmp+cnt+1,cmp2);

for(int i=1;i<=cnt;i++)

for(int j=i+1;j<=cnt;j++)

}return d;

}int main()

for(int i=n+1;i<=n+n;i++)

sort(p+1,p+n+n+1,cmp1);

printf("%.3lf\n",get(1,n+n));

}return

0;}

POJ 3714 Raid 最近點對

求最近點對,只不過這兩個點需要屬於不同的集合,那麼就給兩個集合的點分別標記乙個id號,在計算時,兩個集合合併起來,並排序,遞迴求解,只不過,求兩點距離時,如果id號是同一集合的,直接返回乙個很大的數就行了,這樣就跟求乙個集合的最近點對沒什麼區別了。id sdj22251 prog calfflac ...

POJ 3714 Raid 最近點對

求最近點對,只不過這兩個點需要屬於不同的集合,那麼就給兩個集合的點分別標記乙個id號,在計算時,兩個集合合併起來,並排序,遞迴求解,只不過,求兩點距離時,如果id號是同一集合的,直接返回乙個很大的數就行了,這樣就跟求乙個集合的最近點對沒什麼區別了。id sdj22251 prog calfflac ...

poj 3714 Raid(平面最近點對)

給出兩個點集,然後求兩個點集之間的最近距離。思路 開始用的旋轉卡殼,兩個點集先求凸包,這樣就變成了兩個凸包間最近距離,但是死活tle,然後就換了平面最近點對來做,把兩個點集標記一下,判斷下是不是在同乙個點集裡就行了 include include include using namespace st...