• 洛谷 [P1337] 平衡点


    模拟退火练手

    一道模拟退火的好题
    结果一定势能最小
    与模拟退火思路高度一致

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <ctime>
    using namespace std;
    const int MAXN = 1005;
    struct point {
    	double x, y, wei;
    }poor[MAXN];
    int n;
    const double delta = 0.993;
    const double eps = 1e-14;
    double xans, yans, ans = 1e15, best = 1e15;
    double energy(double x, double y) {
    	double tot = 0.0;
    	for(int i = 1; i <= n; i++) {
    		tot += sqrt((poor[i].x - x) * (poor[i].x - x) + (poor[i].y - y) * (poor[i].y - y)) * poor[i].wei;
    	}
    	return tot;
    }
    double RAND(double T) {
    	return (rand() * 2 - RAND_MAX) * T;
    }
    void solve() {
    	double T = 10000.0;
    	best = ans = energy(xans, yans);
    	double xx = xans, yy = yans;
    	while(T > eps) {
    		double xt = xx + RAND(T);
    		double yt = yy + RAND(T);
    		double anst = energy(xt, yt);
    		double DE = ans - anst;
    		if(DE > 0.0) {
    			xx = xt; yy = yt;
    			ans = anst;
    			if(ans < best) {
    				xans = xx; yans = yy;
    				best = ans;
    			}
    		} else if(exp(DE / T) * RAND_MAX > (double)rand()) {
    			xx = xt; yy = yt;ans = anst;
    		}
    		T *= delta;
    	}
    }
    int main() {
    	srand(time(NULL));
    	cin >> n;
    	for(int i = 1; i <= n; i++) {
    		cin >> poor[i].x >> poor[i].y >> poor[i].wei;
    		xans += poor[i].x; yans += poor[i].y;
    	}
    	xans /= (double)n; yans /= (double)n;
    	solve();
    	solve();
    	solve();
    	printf("%.3f %.3f
    ", xans, yans);
    	return 0;
    }
    
  • 相关阅读:
    [NOIP2008] 传纸条
    [NOIP2006] 能量项链
    [poj2393] Yogurt factory
    [poj3069] Saruman's Army
    [NOIP2011] 观光公交
    [NOIP2010] 关押罪犯
    [洛谷2744] 量取牛奶
    [poj3281] Dining
    关于几类STL容器的swap复杂度问题
    折半法
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/9928919.html
Copyright © 2020-2023  润新知