In order to solve the problem, Dr. Lin made a new invention named Triangle Transmitter. This transmitter is designed to travel among three cities and no matter how long the distance is, we can reach our destination in the three cities in 1 second.
Although the Triangle Transmitter is so excellent, it is so expensive that the king can only build one transmitter to test it. Because it is only for testing, we should make it as cheap as possible. If we build a Triangle Transmitter in three cities, the money we will pay is equal to the sum of the distance between every two cities in the three cities.
Now it is your job to choose three cities to build a Triangle Transmitter so that the king will spend least money. What's more, the king will give you the number of the cities N and the position of each city. The position of each city is described by two integers xi and yi, the distance between two cities is sqrt((x i - x j)^2 + (y i - y j)^2). And no two cities have the same position.
In the first line of each test case, there is one integer N (3<=N<=20000) indicates the number of the cities and the cities are numbered from 1 to N.
Then followed N lines, in each line there are two integers xi and yi (0<=x i,y i<=10^9), indicates the position of each city.
1 4 0 0 0 1 1 0 5 5
3.414
//分治法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define EPS 0.00000001
#define INF 999999999
using namespace std;
//给N个平面上的点,找三个点,使两两距离之和最小,可以不是三角形
struct Point
{
double x,y;
}a[20005];
int n;
int cmp(const struct Point &s,const struct Point &t) //sortº¯Êý
{
if((t.x - s.x) >= EPS)
return 1;
else if(fabs(s.x - t.x) < EPS)
{
if((t.y - s.y) >= EPS)
return 1;
else return 0;
}else return 0;
}
double dis(int i,int j)
{
return sqrt((a[i].x - a[j].x)*(a[i].x - a[j].x) + (a[i].y - a[j].y)*(a[i].y - a[j].y));
}
double cross(Point p0,Point p1,Point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double cal(int l,int r)
{
if(l == r)
return INF;
if(l + 1 == r)
return INF;
if(l + 2 == r)
{
return (dis(l,r) + dis(l,l + 1) + dis(l + 1,r));
}
int mid = (l + r)/2;
double ans = INF;
ans = min(ans,min(cal(l,mid),cal(mid + 1,r)));
for(int i = mid; i >= l; --i)
{
if((fabs(a[i].x - a[mid].x) - ans) > INF)
break;
for (int j = i - 1; j >= l && j >= i - 5; --j)
{
double d = dis(i,j);
if((fabs(d - ans) > INF))
break;
for(int k = mid + 1; k <= r && k <= mid + 5; ++k)
{
ans = min(ans,d + dis(j,k) + dis(i,k));
}
}
for (int j = mid + 1; j <= r && j <= mid + 5; ++j)
{
double d = dis(i,j);
if((fabs(d - ans) > INF))
break;
for(int k = j + 1; k <= r && k <= j + 5; ++k)
{
ans = min(ans,d + dis(j,k) + dis(i,k));
}
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while( T-- )
{
scanf("%d",&n);
for (int i = 1; i <= n; ++i)
scanf("%lf%lf",&a[i].x,&a[i].y);
sort(a + 1, a + n + 1,cmp);
printf("%.3f\n",cal(1,n));
}
return 0;
}