• POJ 2420 A Star not a Tree?【爬山法】


    题目大意:在二维平面上找出一个点,使它到所有给定点的距离和最小,距离定义为欧氏距离,求这个最小的距离和是多少(结果需要四舍五入)?

    思路:如果不能加点,问所有点距离和的最小值那就是经典的MST,如果只可以加一个点问最小值就是广义的费马点的问题,如果加点的数目不加限制,那问题就成了斯坦纳树的问题(介个属于NPC问题)

    这题显然就是广义费马点问题,可以采用局部贪心法,从一个初始点出发,不断向上下左右四个方向拓展,如果在一个方向上走过去到所有点的距离和小于目前这个点到所有点的距离和,那就更新目前点的值,直到从四个方向拓展都不能比目前的点更优,那就说明目前的点属于局部最优,那就减少步长,从刚才给出点处继续搜索,直到精度小于题目所需的精度(整数)

    需要注意的是局部贪心(又叫爬山法)很容易卡在局部最优上,因此往往随机初始点多次,以保证局部最优是全局最优,但广义费马点好像这种局部最优的点不多的样子,选原点为初始点就可以AC这题

    //POJ2420

    #include <cstdio>

    #include <iostream>

    #include <string.h>

    #include <math.h>

    #define maxn 110

    const short dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};

    using namespace std;

    double x[maxn]={0},y[maxn]={0};int n;

    double sumlen(double xx,double yy)

    {

       double ret=0;

       for(int i=1;i<=n;i++)

        {

           ret+=sqrt((xx-x[i])*(xx-x[i])+(yy-y[i])*(yy-y[i]));

        }

       return ret;

    }

    int main()

    {

       scanf("%d",&n);

       for(int i=1;i<=n;i++)scanf("%lf%lf",&x[i],&y[i]);

       double a=0,b=0,min=sumlen(a,b),step=100;

       while (step>0.1)

        {

           short flag=1;

           while (flag==1)//如果这层循环结束,说明从四个方向拓展都不能得到更优解也就是达到了局部最优解

           {

               flag=0;

               for(int i=1;i<=4;i++)

               {

                    doublexx=a+dx[i]*step,yy=b+dy[i]*step,t=sumlen(xx,yy);

                    if (t<min){min=t;a=xx;b=yy;flag=1;}

               }

           }

           step/=2;

        }

       printf("%d",(int)(min+0.5));

       return 0;

    }

  • 相关阅读:
    jsp类的封装集合的应用及servlet的引入和JSTL的引入
    jsp学习1
    小型世界关系图的交互可视化(未完成)
    c++产生随机数问题
    socket error
    opengl空间画圆柱体
    socket连接服务器立即返回,不用三次握手
    win7电脑分无线网,简称热点
    设置ipv6全球地址和默认网关
    网线制作,水晶头里的线顺序
  • 原文地址:https://www.cnblogs.com/philippica/p/4006985.html
Copyright © 2020-2023  润新知