首页 > 代码库 > bzoj3680 -- 模拟退火

bzoj3680 -- 模拟退火

模拟退火裸题(输出"nan nan"可以AC)

代码:

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<cstdlib>
 6 using namespace std;
 7 #define N 10010
 8 struct Node{
 9     double x,y,z;
10 }a[N];
11 double x,y,T=100000,Now,Ax,Ay,X,Y,N2,Min=1e17;
12 int i,j,k,n,m;
13 inline double Dist(double x,double y,Node a){
14     return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y));
15 }
16 inline double Calc(double X,double Y){
17     double Ans=0;
18     for(int i=1;i<=n;i++)Ans+=Dist(X,Y,a[i])*a[i].z;
19     if(Ans<Min)Ax=X,Ay=Y,Min=Ans;
20     return Ans;
21 }
22 inline double Getrand(){
23     return rand()%1000/1000.0;
24 }
25 inline void SA(){
26     while(T>0.001){
27         X=x+T*(Getrand()*2-1);Y=y+T*(Getrand()*2-1);
28         N2=Calc(x,y)-Calc(X,Y);
29         if(N2>0||exp(N2/T)>Getrand())x=X,y=Y;
30         T*=0.993;
31     }
32     for(int i=1;i<=1000;i++){
33         X=Ax+T*(Getrand()*2-1);Y=Ay+T*(Getrand()*2-1);Calc(X,Y);
34     }
35 }
36 int main(){
37     srand(10086);
38     scanf("%d",&n);
39     for(i=1;i<=n;i++)scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].z),x+=a[i].x,y+=a[i].y;
40     x/=n;y/=n;
41     SA();
42     printf("%.3lf %.3lf\n",Ax,Ay);
43     return 0;
44 }
bzoj3680

 

bzoj3680 -- 模拟退火