【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 }