zoukankan      html  css  js  c++  java
  • UVA10228 A Star not a Tree?

    UVA10228 A Star not a Tree?

    题意翻译

    给定一个N边形所有顶点坐标x,y,求其费马点到所有顶点距离和

    费马点是指到多边形所有顶点距离和最小的点

    输入

    第一行为T, T组数据

    第二行正整数N,其后N行,每行两个整数x,y。

    输出

    每行一个数,为所求距离和,精确到整数(每组数据要多输出一个换行,最后一组不用)

    Translated by @BeyondOI

    输入输出样例

    输入 #1

    1
    4
    0 0
    0 10000
    10000 10000
    10000 0
    

    输出 #1

    28284
    

    ​ 这道题做法有三分和模拟退火,我用的是模拟退火。

    ​ 我的模拟退火板子(感谢Tethys的友情支持):

    void SA() {
        double temp = 3000;
        double x = ax , y = ay;
        while(temp > eps) {
            double x1 = x + ((rand() << 1) - RAND_MAX) * temp;
            double y1 = y + ((rand() << 1) - RAND_MAX) * temp;
            double now_ans = calc(x1, y1);
            double del = now_ans - ans;
            if(del < 0) {
                ax = x1, ay = y1;
                x = x1, y = y1; 
                ans = now_ans;
            }
            else 
                if(exp(- del / temp) * RAND_MAX > rand()) 
                    x = x1, y = y1;
            temp *= dwtem;
        }
    }
    

    ​ temp:温度;

    ​ dwtem :每次降温多少;

    ​ del :(Delta)E;

    ​ 公式:(P(Delta E) = e ^ {frac{Delta E}{T}})

    #include <bits/stdc++.h>
        
    using namespace std;
        
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
        
    const int N = 105;
    const double eps = 1e-12;
    const double dwtem = 0.996;
    int n, T;
    double ax, ay, ans, sumx, sumy;
    struct node { double x, y; } a[N];
    
    double calc(double x, double y) {
        double res = 0;
        for(int i = 1;i <= n; i++) 
            res += sqrt((x - a[i].x) * (x - a[i].x) + (y - a[i].y) * (y - a[i].y));
        return res;
    }
    
    void SA() {
        double temp = 3000;
        double x = ax , y = ay;
        while(temp > eps) {
            double x1 = x + ((rand() << 1) - RAND_MAX) * temp;
            double y1 = y + ((rand() << 1) - RAND_MAX) * temp;
            double now_ans = calc(x1, y1);
            double del = now_ans - ans;
            if(del < 0) {
                ax = x1, ay = y1;
                x = x1, y = y1; 
                ans = now_ans;
            }
            else 
                if(exp(- del / temp) * RAND_MAX > rand()) 
                    x = x1, y = y1;
            temp *= dwtem;
        }
    }
    
    int main() {
        
        srand(1e9 + 7);
        T = read();
        for(int i = 1;i <= T; i++) {
            n = read();
            sumx = sumy = 0; ans = 1e11;
            for(int j = 1;j <= n; j++) {
                scanf("%lf %lf", &a[j].x, &a[j].y);
                sumx += a[j].x; sumy += a[j].y;
            }
            ax = sumx / n; ay = sumy / n;
            for(int j = 1;j <= 5; j++) SA();
            printf("%.0lf
    ", ans);
            if(i != T) printf("
    ");
        }
    
        return 0;
    }
    

    (感觉模拟退火好迷呀,都是rand)

  • 相关阅读:
    Spring中的AOP实现思路
    手写IOC-SPRINGPMVC-CONNPOOL
    职责链模式
    判断一个二叉树是不是对称二叉树
    合并区间
    shell命令中用source 和sh(或者bash)执行脚本的区别,以及export的作用
    angular指令的compile,prelink 和 postlink以及controller
    angular的启动原理
    高并发优化方法
    搭建ssm框架的一个小坑
  • 原文地址:https://www.cnblogs.com/czhui666/p/13599753.html
Copyright © 2011-2022 走看看