zoukankan      html  css  js  c++  java
  • [POJ2420]A Star not a Tree?(模拟退火)

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

    求费马点,即到所有其他点总和距离最小的点。

    一开始想枚举一个坐标,另一个坐标二分的,但是check的时候还是O(n)的,复杂度相当于O(n^2lgn),没意义。

    学习一种神贪心,模拟退火。感觉和启发式搜索有点像啊,又有点像牛顿迭代。

      思路就是,固定一个点和一个步长,从这个点开始向四个方向扩展,扩展的步长就是当前步长。如果扩展到的点可以更新答案,那么记住这个点,也就是说这个贪心方向(梯度?)是正确的。就可以拿着这个点继续沿着这个方向走了(剩余的方向可以不考虑了)。

      如果四个方向都不能走,说明步长过长,这个时候模拟退火,将步长按比率缩小。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <cassert>
     8 #include <cstdio>
     9 #include <bitset>
    10 #include <vector>
    11 #include <deque>
    12 #include <queue>
    13 #include <stack>
    14 #include <ctime>
    15 #include <set>
    16 #include <map>
    17 #include <cmath>
    18 using namespace std;
    19 
    20 typedef pair<double, double> pdd;
    21 #define x first
    22 #define y second
    23 const double eps = 1e-8;
    24 const double delta = 0.98;
    25 const int maxn = 10100;
    26 const int dx[5] = {1, -1, 0, 0};
    27 const int dy[5] = {0, 0, 1, -1};
    28 int n;
    29 double ret;
    30 pdd cur;
    31 pdd p[maxn];
    32 
    33 double dist(pdd a, pdd b) {
    34     double p = a.x - b.x;
    35     double q = a.y - b.y;
    36     return sqrt(p * p + q * q);
    37 }
    38 
    39 int main() {
    40     // freopen("in", "r", stdin);
    41     while(~scanf("%d", &n)) {
    42         for(int i = 0; i < n; i++) {
    43             scanf("%lf %lf", &p[i].x, &p[i].y);
    44         }
    45         int t = 100;
    46         ret = 1e100;
    47         cur = pdd(.0, .0);
    48         while(t > eps) {
    49             bool flag = 1;
    50             while(flag) {
    51                 flag = 0;
    52                 for(int i = 0; i < 4; i++) {
    53                     pdd pos = pdd(cur.x+dx[i]*t, cur.y+dy[i]*t);
    54                     double tmp = .0;
    55                     for(int j = 0; j < n; j++) {
    56                         tmp += dist(pos, p[j]);
    57                     }
    58                     if(ret - tmp > eps) {
    59                         ret = tmp;
    60                         cur = pos;
    61                         flag = 1;
    62                         break;
    63                     }
    64                 }
    65             }
    66             t *= delta;
    67         }
    68         printf("%.0f
    ", ret);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    Docker入门
    15个Docker基本命令及用法
    Docker系列
    docker
    Docker 常用命令
    查看用户列表在Linux
    Spring boot Mybatis
    CountDownLatch和CyclicBarrier 专题
    Spring Boot MyBatis 连接数据库
    Spring Boot MyBatis 通用Mapper插件集成 good
  • 原文地址:https://www.cnblogs.com/kirai/p/6229822.html
Copyright © 2011-2022 走看看