POJ 2420 A Star not a Tree

作者: MayFlyyh 分类: 随机算法 发布时间: 2018-07-16 14:20 ė 6 2条评论

给定一个平面和平面上n个点求出一点到所有点的距离和最小输出该最小距离;

很想JS省选吊打XXX

答案是模拟退火,思路明白了以后,重点是每次重新选点的随机方式一定要好。这个一定要多做几道模拟退火领会一下思路。因为我发现不按照题解那样写还真不行。。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
using namespace std;
int n;
double xx,yy,ans,t;
struct point{double x,y;}p[105];
double sqr(double x){return x*x;}
double dis(double x,double y,point p)
{return sqrt(sqr(x-p.x)+sqr(y-p.y));}
double getsum(double x,double y)
{
    double tmp=0;
    for(int i=1;i<=n;i++)
        tmp+=dis(x,y,p[i]);
    return tmp;
}
int main()
{
    srand(time(0));
    while(scanf("%d",&n)!=EOF)
    {
        xx=yy=0;ans=1e20;t=100000;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf",&p[i].x,&p[i].y);
            xx+=p[i].x;yy+=p[i].y;
        }
        xx/=n;yy/=n;
        ans=getsum(xx,yy);
        double tmp,x,y;
        while(t>0.02)
        {
            x=y=0;
            for(int i=1;i<=n;i++)
            {
                x+=(p[i].x-xx)/dis(xx,yy,p[i]);
                y+=(p[i].y-yy)/dis(xx,yy,p[i]);
            }
            tmp=getsum(xx+x*t,yy+y*t);
            if(tmp<ans)
            {ans=tmp;xx+=x*t,yy+=y*t;}
            else if(log((tmp-ans)/t)<(rand()%10000)/10000.0)
            {ans=tmp;xx+=x*t,yy+=y*t;}       
            t*=0.9; 
        }
        printf("%.0lf\n",ans);
    }
    return 0;
}

本文出自MayFlyyh's Blog,转载时请注明出处及相应链接。

本文永久链接: http://www.mayflyyh.com/archives/285

2条评论

  1. 23forever 2018年7月22日 下午12:52 回复

    那题不是jsoi的,jsoi的叫平衡点

    1. MayFlyyh 2018年9月20日 下午6:40 回复

      好吧。。

MayFlyyh进行回复 取消回复

电子邮件地址不会被公开。

Captcha Code

Ɣ回顶部