poj2420 A Star not a Tree?
传送门:http://poj.org/problem?id=2420
【题解】
费马点问题,模拟退火。%.0f神坑
# include <math.h> # include <stdio.h> # include <stdlib.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; const double pi = acos(-1.0); # define RG register # define ST static double minx, maxx, miny, maxy; int n; struct pa { double x, y; double dis; pa() {} pa(double x, double y, double dis) : x(x), y(y), dis(dis) {} }a[M]; namespace SA { const double eps = 1e-2, DEC = 0.9, ACCEPT_DEC = 0.5; const int N = 30, T = 30, RAD = 1000; inline double rand01() { return rand() % (RAD + 1) / (1.0 * RAD); } inline double getdist(double x, double y) { double ret = 0; for (int i=1; i<=n; ++i) ret += sqrt((x-a[i].x)*(x-a[i].x)+(y-a[i].y)*(y-a[i].y)); return ret; } inline pa randpoint(double px, double py, double qx, double qy) { double x = (qx - px) * rand01() + px, y = (qy - py) * rand01() + py; return pa(x, y, getdist(x, y)); } pa res[N + 5]; inline double main() { res[1] = pa((minx+maxx)/2, (miny+maxy)/2, getdist((minx+maxx)/2, (miny+maxy)/2)); for (int i=2; i<=N; ++i) { double x = rand01() * (maxx - minx) + minx; double y = rand01() * (maxy - miny) + miny; res[i] = pa(x, y, getdist(x, y)); } double temper = (maxx+maxy-minx-miny)*n, accept = 0.6; while(temper > eps) { for (int i=1; i<=N; ++i) for (int j=1; j<=T; ++j) { pa t = randpoint(max(res[i].x - temper, minx), max(res[i].y - temper, miny), min(res[i].x + temper, maxx), min(res[i].y + temper, maxy)); if(t.dis < res[i].dis) res[i] = t; else if(rand01() <= accept) res[i] = t; } temper *= DEC; accept *= ACCEPT_DEC; } double dis = 1e18; for (int i=1; i<=N; ++i) if(res[i].dis < dis) dis = res[i].dis; return dis; } } int main() { srand(19260817); while(cin >> n) { maxx = maxy = -1e18, minx = miny = 1e18; for (int i=1; i<=n; ++i) { scanf("%lf%lf", &a[i].x, &a[i].y); maxx = max(maxx, a[i].x); minx = min(minx, a[i].x); maxy = max(maxy, a[i].y); miny = min(miny, a[i].y); } double ans = SA::main(); printf("%.0f\n", ans); } return 0; }