1. 程式人生 > >[POJ2420]A Star not a Tree?

[POJ2420]A Star not a Tree?

logs scan inf const sum nbsp cst 隨機 del

來源:

Waterloo Local 2002.01.26

題目大意:

找出$n$個點的費馬點。

思路:

模擬退火。
首先任取其中一個點(或隨機一個坐標)作為基準點,每次向四周找距離為$t$的點,如果找到的點總距離更小,就把該點作為新的基準點。
每次找完後降低溫度$t$,重復上述過程,直到溫度$t$低於閾值$threshold$。
另外註意在POJ上double類型輸出不能用%lf,只能用%f,一開始因為這個WA了好幾次。

 1 #include<cmath>
 2 #include<cstdio>
 3 const double inf=1e9;
4 const int N=100; 5 const double threshold=1e-8,delta=0.98,initial_temperature=100; 6 const double d[4][2]={{0,1},{1,0},{0,-1},{-1,0}}; 7 int n; 8 struct Point { 9 double x,y; 10 }; 11 Point p[N]; 12 inline double sqr(const double x) { 13 return x*x; 14 } 15 inline double dist(const Point a,const
Point b) { 16 return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)); 17 } 18 inline double getsum(const Point x) { 19 double ret=0; 20 for(int i=0;i<n;i++) { 21 ret+=dist(x,p[i]); 22 } 23 return ret; 24 } 25 int main() { 26 scanf("%d\n",&n); 27 for(int i=0;i<n;i++) {
28 scanf("%lf%lf",&p[i].x,&p[i].y); 29 } 30 Point nowp=p[0]; 31 double ans=getsum(nowp),t=initial_temperature; 32 while(t>threshold) { 33 bool finished=false; 34 while(!finished) { 35 finished=true; 36 for(int i=0;i<4;i++) { 37 Point nextp; 38 nextp.x=nowp.x+d[i][0]*t; 39 nextp.y=nowp.y+d[i][1]*t; 40 double tmp=getsum(nextp); 41 if(tmp<ans) { 42 ans=tmp; 43 nowp=nextp; 44 finished=false; 45 } 46 } 47 } 48 t*=delta; 49 } 50 printf("%.0f\n",ans); 51 return 0; 52 }

[POJ2420]A Star not a Tree?