模拟退火 Wa 87求助玄关
查看原帖
模拟退火 Wa 87求助玄关
577628
zgy_123楼主2024/2/24 14:57

https://www.luogu.com.cn/record/148241338

#include<bits/stdc++.h>
using namespace std;
int x[1005],y[1005],w[1005],n;
double rd(int l,int r){return 1.0*rand()/RAND_MAX*(r-l)+l;}
double xx2,yy2,answ=2e9;
double calc(double xx,double yy){
	double tot=0,dx,dy;
	for(int i=1;i<=n;i++) dx=xx-x[i],dy=yy-y[i],tot+=sqrt(dx*dx+dy*dy)*w[i];
	if(tot<answ) answ=tot,xx2=xx,yy2=yy;
	return tot;
}
void SA(double a,double b){
	double ansx=a,ansy=b;
	for(double T=10000;T>1e-4;T*=0.999){
		double rdx=ansx+rd(-1,1)*T,rdy=ansy+rd(-1,1)*T;
		double delta=calc(rdx,rdy)-calc(ansx,ansy);
		if(exp(-delta/T)>rd(0,1)) ansx=rdx,ansy=rdy;
	}
}
int main(){
	srand(time(0));
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d%d",&x[i],&y[i],&w[i]);
		xx2+=x[i],yy2+=y[i];
	}
	xx2/=n,yy2/=n,answ=calc(xx2,yy2);

while(1.0*clock()/CLOCKS_PER_SEC<0.8) SA(xx2,yy2);
	SA(xx2,yy2);
	for(int i=1;i<=1000;i++) calc(xx2+rd(-0.1,0.1),yy2+rd(-0.1,0.1));
	printf("%.3lf %.3lf",xx2,yy2);
	return 0;
}

加 long double 就全 WA 了。

玄关

2024/2/24 14:57
加载中...