题目大意:给出平面中一些点,求平面中的一个点,使得这个点到其他所有点的距离之和最短,并输出这个距离和。
思路:模拟退火。精度到整数。。。没什么需要注意的。。
话说费马点只能用模拟退火求近似解吧
CODE:
#include
#include
#include
#include
#include
#define MAX 510 #define INF 0x7f7f7f7f #define EPS 1e-2 #define PI acos(-1.0) using namespace std; struct Point{ double x,y; double length; Point(double _x,double _y):x(_x),y(_y) {} Point() {} void Read() { scanf("%lf%lf",&x,&y); } }point[MAX],now,ans; int points; double dE; void Simulated_Annealing(); inline double Rand(); inline double Statistic(Point p); inline double Calc(Point p1,Point p2); int main() { cin >> points; for(int i = 1;i <= points; ++i) point[i].Read(); now = Point(5000.0,5000.0); min_length = Statistic(now); Simulated_Annealing(); printf("%.0f",ans.length); return 0; } void Simulated_Annealing() { double L = 10000.0; while(L > EPS) { double alpha = 2 * PI * Rand(); Point temp(now.x + cos(alpha) * T,now.y + sin(alpha) * T); dE = Statistic(now) - Statistic(temp); if(dE >= 0 || exp(dE / L) > Rand) now = temp; L *= .99; } } inline double Rand() { return (rand() % 1000.0 + 1) / 1000.0; } inline double Statistic(Point p) { double re = 0.0; for(int i = 1;i <= points; ++i) re += Calc(point[i],p); return re; } inline double Calc(Point p1,Point p2) { return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); }