题目意思就是求一个多边形的费马点。
随机贪心算法即可。对于4条边以上的多边形没有公式求解。(三角形则比较简单)。给出这样一个贪心算法:先随机取个点(我选了凸包上的第一个点),再取一个步长(我取100),朝4个方向走,如果新位置到各点距离比原来小,就走过去;直到走不动为止。缩小步长,再走。如此反复,直到步长小于题目的精度(这道题是1.0),走不动了,说明该解达到题目的要求,是最优的,输出。这个贪心基于二维平面的单调性,举个例子,如果目标点在当前点的下面,那么此时往上走就一定不能找出符合要求的点。
以下是代码:
#include<cstdio>
#include<cmath>
using namespace std;
const int M=150;
const double inf=1e250;
struct point
{
double x,y;
}p[M];
int n;
point getpoint(double x,double y)
{
point temp;
temp.x=x;temp.y=y;
return temp;
}
double dist(point a,point b)
{
return sqrt((b.x-a.x)*(b.x-a.x)*1.0+(b.y-a.y)*(b.y-a.y));
}
double alldis(point a)
{
double dis=0;
for(int i=0;i<n;i++)
{
dis+=dist(a,p[i]);
}
return dis;
}
int main()
{
while(scanf("%d",&n)==1)
{
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
point pp=p[0];
double ans=inf,step=100;
ans=alldis(pp);
while(step>0.2)
{
bool flag=true;
while(flag)
{
flag=false;
point qq=getpoint(pp.x,pp.y+step),tt=pp;
double temp=alldis(qq);
if(temp<ans)
{
ans=temp;
tt=qq;
flag=true;
}
qq=getpoint(pp.x,pp.y-step);
temp=alldis(qq);
if(temp<ans)
{
ans=temp;
tt=qq;
flag=true;
}
qq=getpoint(pp.x+step,pp.y);
temp=alldis(qq);
if(temp<ans)
{
ans=temp;
tt=qq;
flag=true;
}
qq=getpoint(pp.x-step,pp.y);
temp=alldis(qq);
if(temp<ans)
{
ans=temp;
tt=qq;
flag=true;
}
pp=tt;
}
step=step/2.0;
}
int dis=(int)(ans+0.5)*100/100;
printf("%d\n",dis);
}
return 0;
}