BZOJ 3680 模拟退火

来源:互联网 发布:linux send 返回值 编辑:程序博客网 时间:2024/05/22 15:01
#include <stdio.h>#include <string>#include <cstring>#include <queue>#include <algorithm>#include <functional>#include <vector>#include <sstream>#include <iomanip>#include <math.h>#include <iostream>#include <sstream>#include <time.h>#include <stack>#include <set>#include <map>#include <time.h>#include <bitset>#define INF (1e17)#define EPS (1e-3)#define PI  (acos(-1.0))#define FIRE(x) (x *= 0.97)using namespace std;const int MAXN = 10000 + 10;int N;double total = INF;struct Point{    double x, y, w;    Point (double _x, double _y) : x(_x), y(_y) {}    Point (void) {}    void Read(void)    {        cin>>x>>y>>w;    }    void operator += (Point t)    {        x += t.x;        y += t.y;    }    void operator /= (int N)    {        x /= N, y /= N;    }};Point now, ans, point[MAXN];inline double Dist(Point a, Point b){    return sqrt((a.x - b.x) * (a.x - b.x) +                (a.y - b.y) * (a.y - b.y));}inline double Statistic(Point p){    double res = 0.0;    for (int i = 0; i < N; i++)        res += Dist(p, point[i]) * point[i].w;    if (res < total)        total = res, ans = p;    return res;}inline double Rand(void){    return (rand() % 1000 + 1) / 1000.0;}int main(void){    cin.sync_with_stdio(false);    cout<<fixed<<setprecision(3);    srand(1);    cin>>N;    register int i;    for (i = 0; i < N; i++)        point[i].Read(), now += point[i];    now /= N;    double T = 100000.0, alpha, sub;    while (T > EPS)    {        alpha = 2.0 * PI * Rand();        Point tmp(now.x + T * cos(alpha), now.y + T * sin(alpha));        sub = Statistic(now) - Statistic(tmp);        if(sub >= 0 || exp(sub / T) >= Rand())            now = tmp;        FIRE(T);    }    T = 0.001;    for (i = 1; i <= 1000; ++i)    {        alpha = 2.0 * PI * Rand();        Point tmp(ans.x + T * cos(alpha) * Rand(), ans.y + T * sin(alpha) * Rand());        Statistic(tmp);    }    cout<<ans.x<<' '<<ans.y<<endl;    return 0;}
0 0