POJ 3714 Raid 平面最近點對

2021-06-28 04:45:50 字數 1477 閱讀 3034

題目大意:給出兩個集合的點,問這兩個集合之間最近的點對的距離是多少。

思路:先要知道平面最近點對的分治演算法,剩下的就簡單了,只需要在更新答案的時候判斷一下兩個點是否屬於兩個集合就可以了。

分治演算法總是十分神奇的。

對於平面最近點對,首先按照x座標排序,然後遞迴進行分治,每次分治時,先獲得分治得到的結果,然後按照這個結果來計算本區間。由於我們只需要計算答案小於這個結果的點對就行了,其中(l,mid)和(mid + 1,r)我們已經得到答案,只需要統計乙個點在(l,mid),另乙個點在(mid + 1,r)的所有點對了。但是這還是很大。

有乙個強剪枝,設立中軸為(x[mid] + x[mid + 1]) / 2,我們只需要統計在這個中軸兩側不超過之前算過的最小值的點就可以了,因為其他的點對不可能更新答案。

還有乙個剪枝,每次找到這些點之後,再按照y座標排序,之後發現y座標相差超過之前算過的最小值的點對也肯定不能更新答案,對於乙個點來說能夠更新答案的點在另一側是乙個單調的區間,只需要乙個指標掃一下就行了。

code:

#include #include #include #include #include #include #define max 200010

#define inf 1e15

using namespace std;

struct point

void read(bool _)

}point[max],l[max],r[max];

int points;

inline double calc(const point &p1,const point &p2)

bool cmp(const point &p1,const point &p2)

double solve(int l,int r)

int mid = (l + r) >> 1;

re = min(re,solve(l,mid));

re = min(re,solve(mid + 1,r));

double x = (point[mid].x + point[mid + 1].x) / 2.0;

int pl = mid,pr = mid + 1;

int ltop = 0,rtop = 0;

while(x - point[pl].x <= re && pl >= l) l[++ltop] = point[pl--];

while(point[pr].x - x <= re && pr <= r) r[++rtop] = point[pr++];

sort(l + 1,l + ltop + 1,cmp);

sort(r + 1,r + rtop + 1,cmp);

int start = 1;

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

return re;

}int main()

return 0;

}

poj 3714 Raid(平面最近點對)

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

poj 3714 Raid(平面最近點對)

題意 給定在同一平面中,同數量黑點與白點的座標值,求其中最近黑白點對的距離。大水題一遍過qaq 稍微做點工作就是把同顏色的點,做上標記,同顏色的點就使其之間距離inf 分治or暴力 剪枝都可以過。include include include include include using namesp...

POJ 3714 Raid 最近點對

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