【POJ】【2420】A Star not a Tree?

模拟退火

  Orz HZWER

  这题的题意是在二维平面内找一点,使得这点到给定的n个点的距离和最小……0.0

  模拟退火算法请戳这里

 1 //POJ 2420
 2 #include<ctime>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 using namespace std;
13 int getint(){
14     int v=0,sign=1; char ch=getchar();
15     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
16     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
17     return v*sign;
18 }
19 /*******************template********************/
20 int n;
21 double x,y,ans,t;
22 struct point{double x,y;} p[110];
23 
24 double dis(double x,double y,point p){
25     return sqrt( (p.x-x)*(p.x-x)+(p.y-y)*(p.y-y) );
26 }
27 double getsum(double x,double y){
28     double temp=0;
29     F(i,1,n) temp+=dis(x,y,p[i]);
30     return temp;
31 }
32 int main(){
33     srand(time(0));
34     while(scanf("%d",&n)!=EOF){
35         x=y=0; ans=1e20; t=1e5;
36         F(i,1,n){
37             scanf("%lf%lf",&p[i].x,&p[i].y);
38             x+=p[i].x; y+=p[i].y;
39         }
40         x/=n; y/=n;
41         ans=getsum(x,y);//初始解 
42         double tmp,tx,ty;
43         while(t>0.02){
44             tx=ty=0;
45             F(i,1,n){
46                 tx+=(p[i].x-x)/dis(x,y,p[i]);
47                 ty+=(p[i].y-y)/dis(x,y,p[i]);
48             }
49             tmp=getsum(x+tx*t,y+ty*t);
50             //生成一个新解tmp 
51             if (tmp<ans){
52                 ans=tmp; x+=tx*t; y+=ty*t;
53             }//接受较优解 
54             else if( log((tmp-ans)/t) < (rand()%10000)/10000.0 ){
55                 ans=tmp; x+=tx*t; y+=ty*t;
56             }//一定概率接受较差解 (由于t越来越小,所以接受较差解的概率也越来越小……) 
57             t*=0.9;//“降温” 
58         }
59         printf("%.0f\n",ans);
60     }
61     return 0;
62 }
View Code(带注释)

 

posted @ 2015-02-03 21:00  Tunix  阅读(178)  评论(0编辑  收藏  举报