zoukankan      html  css  js  c++  java
  • poj 2420,模拟退火算法,费马点

    题目链接:http://poj.org/problem?id=2420

    题意:给n个点,找出一个点,使这个点到其他所有点的距离之和最小,也就是求费马点。

    参考链接:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

    这一篇文章写的很好,我这个小白都有一点小明白了。

    记一下笔记:

    模拟退火: 就是在一定范围内接受一些不是最优的解,来跳出局部最优,靠近整体最优。

    贴一下伪代码:

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<deque>
    #include<functional>
    #include<iterator>
    #include<set>
    #include<utility>
    #include<stack>
    #include<queue>
    #include<iomanip>
    #include<cmath>
    
    using namespace std;
    
    #define N 1005
    #define eps 1e-8
    #define INF 1e99
    #define delta 0.98
    #define T 100
    
    int dx[4] = {0,0,-1,1};
    int dy[4] = {-1,1,0,0};
    
    struct Point
    {
        double x,y;
    } p[N];
    
    double dist (Point a,Point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    double GetSum(Point p[],int n,Point t)
    {
        double ans = 0;
        while(n--)
        {
            ans+=dist(p[n],t);
        }
        return ans;
    }
    
    double Search(Point p[],int n)
    {
        Point s = p[0];
        double t = T;
        double ans = INF;
        while(t>eps)
        {
            bool flag = 1;
            while(flag)
            {
                flag = 0;
                for(int i=0; i<4; i++)
                {
                    Point z;
                    z.x = s.x + dx[i]*t;
                    z.y = s.y + dy[i]*t;
                    double tp = GetSum(p,n,z);
                    if(ans>tp)
                    {
                        ans = tp;
                        s = z;
                        flag = 1;
                    }
                }
            }
            t*=delta;
        }
        return ans;
    }
    
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            for(int i=0; i<n; i++)
                scanf("%lf%lf",&p[i].x,&p[i].y);
            printf("%.0lf
    ",Search(p,n));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    解题:POI 2009 TAB
    解题:POI 2015 Pieczęć
    解题:POI 2013 Taxis
    解题:POI 2015 Kinoman
    题目1012:畅通工程(并查集)
    并查集深入分析
    题目1186:打印日期(日期计算)
    C/C++如何整行读入字符串?
    四种方法解决最大连续子序列和问题
    题目1011:最大连续子序列
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5929040.html
Copyright © 2011-2022 走看看