[BZOJ 3680]吊打XXX(广义费马点、模拟退火搜索)

来源:互联网 发布:grub安装ubuntu 编辑:程序博客网 时间:2024/05/22 09:43

http://www.lydsy.com/JudgeOnline/problem.php?id=3680

题目大意:求n个带质量的质点的重心,重心定义为与每个点的距离*点的质量之和最小的点。

此题是ICPC Camp第一场Finals模拟赛中yyf神牛的D题解法,就是裸的模拟退火搜索,虽然说精度要求略有些苛刻(1e-3),不过在Finals模拟赛中yyf经过28次调整精度还能实现1e-6的精度,应该问题不大,不过如果代码写得很挫(比如说随机数写挂了),就可能WA或TLE

#include <stdio.h>#include <stdlib.h>#include <stdlib.h>#include <algorithm>#include <cmath> #define MAXN 10100#define INF 1e17#define EPS 1e-3#define PI acos(-1.0) using namespace std; double minans=INF; //最小答案(重心到各点距离的加权和) struct Point{    double x,y; //点的坐标(x,y)    double weight; //质量}points[MAXN],centerOfGravity; //centerOfGravity=最终的重心质点 int n; //点的个数 double EuclidDist(Point p1,Point p2) //求点p1到p2的距离{    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));} double calc(Point x) //用当前假设的重心x更新最小的答案minans,并返回当前假设的重心x得到的最小加权距离和{    double ans=0; //当前用点x作重心的情况下重心x到各点距离的加权和    for(int i=1;i<=n;i++)        ans+=points[i].weight*EuclidDist(x,points[i]);    if(ans<minans)    {        minans=ans;        centerOfGravity=x;    }    return ans;} double Rand(){    return (rand()%1000)/1000.0;} void SA(double T) //模拟退火搜索找n个点的重心,最初的温度是T{    Point now=centerOfGravity;    while(T>EPS)    {        Point next;        next.x=now.x+T*(Rand()*2-1);        next.y=now.y+T*(Rand()*2-1);        double dE=calc(now)-calc(next); //改变重心位置的能量差dE        if(dE>0||exp(dE/T)>Rand()) now=next; //移动当前的点now        T*=0.993;    }    for(int i=1;i<=1000;i++) //为了使答案更加精确,在最终确定的重心周围再随机地移动一丁点小步,更新答案    {        Point next;        next.x=centerOfGravity.x+T*(Rand()*2-1);        next.y=centerOfGravity.y+T*(Rand()*2-1);        calc(next);    }} int main(){    srand(23333333);    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%lf%lf%lf",&points[i].x,&points[i].y,&points[i].weight);        centerOfGravity.x+=points[i].x;        centerOfGravity.y+=points[i].y;    }    //大致确定重心的位置    centerOfGravity.x/=n;    centerOfGravity.y/=n;    SA(1000000);    printf("%.3lf %.3lf\n",centerOfGravity.x,centerOfGravity.y);    return 0;}


0 0
原创粉丝点击