最近點對:
對所有點按照 x座標排序。然後分治,求出左半邊和右半邊的最近點對,對於兩邊的最近距離取較小的,記為 d。取從分治的中間點向左右各距離為 d d的範圍中的所有點,把這些點按照 y座標排序。對於每個點,掃一下與它 y座標差小於等於 d的點,更新答案,可以證明(證明沒看懂=_=)這樣的點是很少的,不超過6個。
該題題意:給定n個點的座標,第i個點消失後的最近點對距離為di,求di的和。
這題解法: 因為如果消失的點不是最近點對,那麼對答案是沒有影響的。
所以可以先求出沒消失之前的最近點距離*(n-2),(n-2)指的是消失的點不是最近點對。再分別求兩個最近點消失後的最近點距離。
#include
#include
#include
#include
#include
#define x first
#define y second
using
namespace
std;
typedef
long
long ll;
struct point
p[100005];
int tmp[100005];
int a,b;
ll mn=1ll<<54;
bool cmpxy(point a,point b)
void update(int a,int b)//更新[1,n]的最近點對
}ll closest(int l,int r)
int mid=(l+r)>>1;
ll ret=min(closest(l,mid),closest(mid+1,r));
int k=0;
for(int i=l;i<=r;i++)
sort(tmp,tmp+k,cmpy);
for(int i=0;ifor(int j=i+1;j1ll*(p[tmp[j]].y-p[tmp[i]].y)*(p[tmp[j]].y-p[tmp[i]].y)<=ret;j++)
return ret;
/*ret為[l,r]區間的最近點距離的d^2,所以前面都是類似這種
(p[mid].x-p[i].x)*(p[mid].x-p[i].x)<=ret
用來表示x座標差小於d
}int main()
{#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int t;
scanf("%d",&t);
while(t--)
{int n;
ll ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+1+n,cmpxy);
closest(1,n);
ans+=mn*(n-2);
mn=1ll<<50;
int a=a,b=b;
for(int i=1;i<=n;i++)
if(i==a) swap(p[i],p[n]);
closest(1,n-1);
ans+=mn;
mn=1ll<<50;
for(int i=1;i<=n;i++)
if(i==b) swap(p[i],p[n]);
closest(1,n-1);
ans+=mn;
mn=1ll<<50;
cout<
hdu1007 最近點對
題意 給你n個點,讓你求最近的兩個點的距離是多少.思路 這個題目我沒思路,我在網上看的是什麼分治 鴿巢原理,分治我知道,鴿巢原理我也知道,但是這個題目就是沒有證明出來他和鴿巢原理有jm關係,總之就是先以x或者y優先sort一下,然後每次列舉每個相鄰點的附近5個就行了 加自己一共六個 而且這個題目的前...
HDU 1007 最近點對
分治法求最近點對 遞迴將點不斷分成小組,計算最短距離。此時的最短距離僅僅是兩點都屬兩塊的某一塊 這裡的分割點是mid點 還需要考慮兩點分屬兩塊的情況。這時對於選點則把範圍縮小到了以mid為中心。再將距離mid點x軸2 mindist範圍點考慮在內。在這些點中,再取mid點,留下那些 y的距離不大於m...
hdu 1007 最近點對
最近點對問題定義 已知上m個點的集合,找出對接近的一對點。在二維空間裡,可用分治法求解最近點對問題。預處理 分別根據點的x軸和y軸座標進行排序,得到x和y,很顯然此時x和y中的點就是s中的點。情況 1 點數小於等於三時 情況 2 點數大於三時 首先劃分集合s為sl和sr,使得sl中的每乙個點位於sr...