P2210 Haywire

数据范围小地可怜
那就模拟退火

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int ans[50];
int son[50][5];
int n;
int tem[50];
int x,y,z;
double delat=0.996;
int anss;
int cal(){
	int ans=0;
	for(int i=1;i<=n;++i){
		ans+=abs(tem[i]-tem[son[i][0]]) +abs(tem[i]-tem[son[i][2]])+abs(tem[i]-tem[son[i][1]]);
	}
	return ans;
}
void sa(){
	for(int i=1;i<=n;++i){
	tem[i]=ans[i]; 
	} 
	double t=2000;
	int temm=anss;
	while(t>=1e-15){
		int nx=rand()%n+1;
		int ny=rand()%n+1;
		if(nx==ny) continue;
		swap(tem[nx],tem[ny]);
		int res=cal();
		int rres=res-temm;
		if(rres<0){
			for(int i=1;i<=n;++i)
				ans[i]=tem[i];
			anss=temm=res;
		}else{
			if(exp(-rres/t)*RAND_MAX<rand())
			swap(tem[nx],tem[ny]);
			else{
				temm=res;
			}
		}
		t*=delat; 
	}
}
int main(){
	srand(20040519);
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%d%d",&son[i][0],&son[i][1],&son[i][2]);
		ans[i]=tem[i]=i; 
	}
	anss=cal();
	sa();
	sa();
	sa();
	cout<<anss/2<<endl;
	return 0;
} 
posted @ 2021-07-21 15:37  Simex  阅读(17)  评论(0编辑  收藏  举报