模拟退火 & UVA10228 A Star not a Tree?
洛谷传送门
模拟退火
推荐一篇感觉写得很好的洛谷日报
补充一点就是可以加个判断(这个题因为有多组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;
}