zoukankan      html  css  js  c++  java
  • bzoj 3680: 吊打XXX 模拟退火

    题目大意:

    给定n个点及每个点的附加权值,求一个点使其到这n个点的加权距离和最小.
    ((n leq 100000))

    题解:

    同poj 2420
    把将状态映射到实数的函数改一改就行了.

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    inline void read(int &x){
    	x=0;char ch;bool flag = false;
    	while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 10010;
    const double eps = 1e-3;
    const double det = 0.99;
    const double pi = acos(-1.0);
    struct Point{
    	double x,y;
    	Point(const double&a=0,const double &b=0){x=a;y=b;}
    };
    inline double sqr(const double &x){return x*x;}
    inline double dis(const Point &a,const Point &b){
    	return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
    }
    Point p[maxn],nw,ans;
    double ans_min = 1e100;
    int n,w[maxn];
    double f(const Point &x){
    	double ret = 0;
    	for(int i=1;i<=n;++i) ret += dis(x,p[i])*w[i];
    	if(ret < ans_min) ans_min = ret,ans = x;
    	return ret;
    }
    inline double ran(){
    	return (double)(rand() % 1000 + 1)/1000.0;
    }
    int main(){
    	srand(2333);
    	read(n);
    	for(int i=1,x;i<=n;++i){
    		read(x);nw.x+=x;p[i].x = x;
    		read(x);nw.y+=x;p[i].y = x;
    		read(w[i]);
    	}nw.x /= 1.0*n;nw.y /= 1.0*n;
    	double T = 1000.0,x,de;
    	bool flag = false;
    	while(T > eps){
    		flag = true;
    		while(flag){
    			flag = false;
    			for(int i=1;i<=4;++i){
    				x = pi*2.0*ran();
    				Point nx(nw.x+T*cos(x),nw.y+T*sin(x));
    				de = f(nw) - f(nx);
    				if(de > 0 || exp(de/T) > ran()){
    					nw = nx;flag = true;
    				}
    				T *= det;
    			}
    		}
    	}
    	T = eps;
    	for(int i=1;i<=1000;++i){
    		x = pi*2.0*ran();
    		f(Point(ans.x+T*cos(x)*ran(),ans.y+T*sin(x)*ran()));
    	}
    	printf("%.3lf %.3lf
    ",ans.x,ans.y);
    	getchar();getchar();
    	return 0;
    }
    
  • 相关阅读:
    javascript回调函数笔记
    JavaScript回调函数的实现
    深入理解JS执行细节(写的很精辟)
    javascript中return function与return function()的区别
    windows下dubbo-admin2.6.x之后版本的安装
    shiro经典通俗易懂javase例子
    字符串转数字练习--String to Integer (atoi)
    字符串按照Z旋转90度然后上下翻转的字形按行输出字符串--ZigZag Conversion
    SQL ----post漏洞测试注入
    nginx笔记----解决windows80端口被iis占用
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6438263.html
Copyright © 2011-2022 走看看