POJ2420
题解:广义费马点,利用模拟退火算法。记录一下
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
double const inf = 1e8;
double const eps = 1e-8;
int const N = 100 + 10;
int n;
double d[][2] = {0,1,1,0,0,-1,-1,0};
struct Point
{
double x,y;
Point(){};
Point(double x,double y):x(x),y(y){};
};
Point p[N];
double dis(Point a,Point b){
return hypot(a.x - b.x,a.y - b.y);
}
double getsum(Point s){
double sum = 0;
for(int i=0;i<n;i++)
sum += dis(s,p[i]);
return sum;
}
double solve(){
double ans = inf;
Point ret = p[0];
for(double t=inf;t>eps;t *= 0.95){ //调节温度
int flag = true;
while(flag){
flag = false;
for(int i=0;i<4;i++){ //是否达到迭代次数
double dx = ret.x + d[i][0] * t;
double dy = ret.y + d[i][1] * t;
double len = getsum(Point(dx,dy));
if(len < ans){
ans = len;
ret = Point(dx,dy);
flag = true; //继续找局部最优解
break;
}
}
}
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
printf("%.0f\n",solve());
return 0;
}