模拟退火90pts WA on #10 #12 求助
  • 板块P1433 吃奶酪
  • 楼主Point_LUO
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/5/31 23:31
  • 上次更新2024/6/1 09:51:19
查看原帖
模拟退火90pts WA on #10 #12 求助
609818
Point_LUO楼主2024/5/31 23:31

rt

#include<bits/stdc++.h>
using namespace std;
int n;
double ans;
bool vis[20];
int path[20];// 路径记录 
struct P
{
	double x=0,y=0;
}a[20];
double D(double xa,double ya,double xb,double yb) { return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb)); }
double L()
{
	double res=0;
	for(int i=1;i<=n;i++) res+=D(a[path[i-1]].x,a[path[i-1]].y,a[path[i]].x,a[path[i]].y);
	return res;
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
	if(n==1) { printf("%.2lf",D(0,0,a[1].x,a[1].y)); return 0; }
	for(int i=1;i<=n;i++)// 贪心计算初始答案 
	{
		double d=1e12;
		int tmp=-1;
		for(int j=1;j<=n;j++)
		{
			if(vis[j]) continue;
			if(tmp==-1||d>D(a[path[i-1]].x,a[path[i-1]].y,a[j].x,a[j].y))
			{
				d=D(a[path[i-1]].x,a[path[i-1]].y,a[j].x,a[j].y);
				tmp=j;
			}
		}
		path[i]=tmp;
		vis[path[i]]=1;
	}
	ans=L();
	double t=1190;
	while(clock()<CLOCKS_PER_SEC*0.9)//模拟退火 
	{
		int s=(rand()%n+n)%n+1;
		int e=(rand()%n+n)%n+1;
		while(e==s) e=(rand()%n+n)%n+1;
		swap(path[s],path[e]);
		double tmp=L();
		if(ans>tmp) ans=tmp;
		else if(exp((ans-tmp)/t)*RAND_MAX*5000<rand()) swap(path[s],path[e]);
		t*=0.9995;
	}
	printf("%.2lf\n",ans);
	return 0;
}
2024/5/31 23:31
加载中...