hdu 3868 The Triangle ransmitter 给N个平面上的点,找三个点,使两两距离之和最小,可以不是三角形
2011-07-28 16:11
435 查看
[align=left]Problem Description[/align]The Kingdom of Silence is a beautiful country. There are N cities in the kingdom. There are several highways so that people can go from a city to another one. But there are so many cars in the kingdom that there are too many traffic congestions in the kingdom.
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((xi - xj)^2 + (yi - yj)^2). And no two cities have the same position.
[align=left]Input[/align]The first line contains a single integer T, the number of test cases. And then followed T cases.
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<=xi,yi<=10^9), indicates the position of each city.
[align=left]Output[/align]The output should contain T lines. For each test case you should just output an real number with exactly three digits after a decimal point which is the least money that the king have to pay.
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
//分治法
#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;
}
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((xi - xj)^2 + (yi - yj)^2). And no two cities have the same position.
[align=left]Input[/align]The first line contains a single integer T, the number of test cases. And then followed T cases.
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<=xi,yi<=10^9), indicates the position of each city.
[align=left]Output[/align]The output should contain T lines. For each test case you should just output an real number with exactly three digits after a decimal point which is the least money that the king have to pay.
[align=left]Sample Input[/align]
1 4 0 0 0 1 1 0 5 5
[align=left]Sample Output[/align]
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;
}
相关文章推荐
- HDU 1249 三角形 三角形最多可以把平面分成几个区域? 递推找规律题
- HDU-用N个三角形最多可以把平面分成几个区域
- Hdu 5807 Keep In Touch(有三个人分别在三个位置,每一秒各走一步,三个城市可以联络的要求是两两权值差小于等于K。 问有多少种不同的方案,让这三个人可以联络。)
- hdu 1007 N个点中输出2点的最小距离的一半
- 最近距离 已知平面上的若干点的位置,存入一个List中。现在需要计算所有这些点中, 距离最近的两个点间的最小距离。请补全缺失的代码。
- [LintCode 382]给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?
- (hdu 7.1.8)Quoit Design(最低点——在n一个点,发现两点之间的最小距离)
- 分治算法应用–求平面两点之间的最小距离
- POJ 3241 Object Clustering 二维平面曼哈顿距离最小生成树
- 某曲线上的点到两点距离和最小的问题都可以用做椭圆解决
- !HDU 4311 最小曼哈顿距离-思维&卡时间-(横纵坐标分开算,排序)
- 【伪原题】平面上最小三角形
- HDU 4311 Meeting point-1(曼哈顿距离最小)
- HDU 3458 Enumerate the Triangles(最小周长三角形)
- hdu 2122(Ice_cream’s world III)(最小生成树,两种算法都可以)
- 某曲线上的点到两点距离和最小的问题都可以用做椭圆解决
- 寻找距离最小的平面点对——分治方法
- LeetCode 16. 3Sum Closest--寻找数组中的三个元素和,该和与给定的值的差最小,输出这个和(三个元素可以不连续)
- BZOJ 2458 最小三角形 | 平面分治
- hdu__1249 三角形(分割平面) f附上相似问题规律讲解