模擬退火 & UVA10228 A Star not a Tree?
阿新 • • 發佈:2021-07-16
洛谷傳送門
模擬退火
推薦一篇感覺寫得很好的洛穀日報
補充一點就是可以加個判斷(這個題因為有多組T不適用):
while ((double)clock()/CLOCKS_PER_SEC<MAX_TIME) SA();
注意這個題的輸出格式特別狗……
AC程式碼
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<ctime> using namespace std; const double delta=0.996; int T,n; double ans,ansx,ansy,sumx,sumy; struct node{ double x,y; }a[105]; double work(double x,double y){ double ans=0; for(int i=1;i<=n;i++){ ans+=sqrt((x-a[i].x)*(x-a[i].x)+(y-a[i].y)*(y-a[i].y)); } return ans; } void SA(){ double t=3000,x=ansx,y=ansy; while(t>1e-15){ double newx=x+(rand()*2-RAND_MAX)*t,newy=y+(rand()*2-RAND_MAX)*t; double res=work(newx,newy); double cha=res-ans; if(cha<0) ansx=x=newx,ansy=y=newy,ans=res; else{ if(exp(-cha/t)*RAND_MAX>rand()) x=newx,y=newy; } t*=delta; } } int main(){ ios::sync_with_stdio(false); srand(time(NULL)); cin>>T; while(T--){ cin>>n; for(int i=1;i<=n;i++){ int x,y; cin>>x>>y; a[i].x=x; a[i].y=y; sumx+=x; sumy+=y; } ansx=sumx/n; ansy=sumy/n; ans=1e8; for(int i=1;i<=10;i++) SA(); if(T>=1) cout<<round(ans)<<endl<<endl; else cout<<round(ans)<<endl; } return 0; }