hdu 5721
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define Pr pair<int,int>
#define fread(ch) freopen(ch,"r",stdin)
#define fwrite(ch) freopen(ch,"w",stdout)
using namespace std;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int msz = 100100;
const int mod = 1e9+7;
const double eps = 1e-8;
struct Point
{
LL x,y;
int id;
};
LL dist(Point a,Point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
Point p[msz];
Point tmpt[msz];
bool cmpxy(Point a,Point b)
{
if(a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
bool cmpy(Point a,Point b)
{
return a.y < b.y;
}
LL d;
int pt[2];
void Closest_Pair(int left,int right,int opt)
{
if(left == right) return;
LL tmp;
if(left + 1 == right)
{
if(p[left].id != opt && p[right].id != opt)
{
tmp = dist(p[left],p[right]);
if(d > tmp)
{
d = tmp;
if(opt == -1)
{
pt[0] = p[left].id;
pt[1] = p[right].id;
}
}
}
return;
}
int mid = (left+right)/2;
Closest_Pair(left,mid,opt);
Closest_Pair(mid+1,right,opt);
int k = 0;
for(int i = left; i <= right; ++i)
{
if(p[i].id != opt && abs(p[mid].x - p[i].x) <= d)
tmpt[k++] = p[i];
}
sort(tmpt,tmpt+k,cmpy);
for(int i = 0; i < k; ++i)
{
for(int j = i+1; j < k && tmpt[j].y - tmpt[i].y < d; ++j)
{
tmp = dist(tmpt[i],tmpt[j]);
if(d > tmp)
{
if(opt == -1)
{
pt[0] = tmpt[i].id;
pt[1] = tmpt[j].id;
}
d = tmp;
}
}
}
}
int main()
{
//fread("");
//fwrite("");
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i = 0; i < n; ++i)
{
scanf("%lld%lld",&p[i].x,&p[i].y);
p[i].id = i;
}
sort(p,p+n,cmpxy);
d = INF;
Closest_Pair(0,n-1,-1);
LL ans = 1LL*d*(n-2);
d = INF;
Closest_Pair(0,n-1,pt[0]);
ans += d;
d = INF;
Closest_Pair(0,n-1,pt[1]);
ans += d;
printf("%lld\n",ans);
}
return 0;
}
平面点集最短距离,记录两点的代码!
最新推荐文章于 2023-12-18 23:07:31 发布