/* 题意:给n个电脑,求一个点到这n个电脑的距离和最小。 模拟退火法:和poj1379的方法类似 因为坐标范围是0-10000 不妨把它看成是10000*10000的正方形来做 */ #include<stdio.h> #include<math.h> #include<iostream> #include<algorithm> #define inf 10000000000000 using namespace std; #define N 110 #define eps 0.1 #define pi acos(-1.0) struct node { double x,y,dis; }f[N],ff[N]; int n; double dd,x,y; double diss(double x,double y) { double sum=0; int i; for(i=1;i<=n;i++) sum=sum+sqrt((x-f[i].x)*(x-f[i].x)+(y-f[i].y)*(y-f[i].y)); return sum; } void slove() { int i,j; double xx,yy; for(i=1;i<=20;i++) { ff[i].x=rand()%10000*1.0+1; ff[i].y=rand()%10000*1.0+1; ff[i].dis=diss(ff[i].x,ff[i].y); } double T=10000.0*sqrt(2.0); double rate=0.9; while(T>eps) { for(i=1;i<=20;i++) for(j=1;j<=30;j++) { double ran=(rand()%1000+1)/1000.0*pi*10; xx=ff[i].x+cos(ran)*T; yy=ff[i].y+sin(ran)*T; double dis=diss(xx,yy); if(xx<0.0||xx>10000.0||yy<0.0||yy>10000.0)continue; if(dis<ff[i].dis) ff[i].dis=dis; } T*=rate; } dd=inf; for(i=1;i<=20;i++){ if(dd>ff[i].dis) dd=ff[i].dis; } return ; } int main() { int i; while(scanf("%d",&n)!=EOF) { x=inf; y=-1; for(i=1;i<=n;i++) scanf("%lf%lf",&f[i].x,&f[i].y); slove(); printf("%.0f ",dd); } return 0; }