欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[NOIP2017]_D2T2 宝藏

程序员文章站 2022-03-14 23:51:02
...

广为Oier所知的状压题,就不提供链接了(其实还是我懒)

解法:

         奇(chao)妙(bu)玄(zheng)学(jing)的模拟退火算法

程序:

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
inline int read(){
	char c=getchar();int num=0;int f=1;
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){num=(num<<3)+(num<<1)+(c^48);c=getchar();}
	return num*f;
}
inline void qwq(int x){
	if(x>9)qwq(x/10);
	putchar(x%10+'0');
}
inline void write(int x){
	if(x<0){x=-x;putchar('-');}
	qwq(x);putchar('\n');
}
int n;
int maps[15][15];
int temp[15];int temp2[15];
int dep[15];

inline int dis(int a[]){
	memset(dep,0,sizeof(dep));
	dep[a[1]]=1;int re_value=0;
	rep(i,2,n){
		int tempx=INT_MAX;int xi=0;
		rep(j,1,n){
			if(a[i]==j)continue;
			if(maps[a[i]][j]!=INT_MAX&&dep[j]){
				if(maps[a[i]][j]*dep[j]<tempx){
					tempx=maps[a[i]][j]*dep[j];
					xi=j;
				}
			}
		}
		if(tempx==INT_MAX)return INT_MAX;
		re_value+=tempx;
		dep[a[i]]=dep[xi]+1;
	}
	return re_value;
}
inline bool O_K(double x,double y){
	if(x<=0)return true;
	return rand()<=exp((-x)/y)*RAND_MAX;
}
inline int solve(){
	double temper=1024;
	random_shuffle(temp+1,temp+n+1);
	rep(i,1,n){temp2[i]=temp[i];}
	int re_value=dis(temp);
	while(temper>0.01){
		int nop1=rand()%n+1;int nop2=rand()%n+1;
		swap(temp2[nop1],temp2[nop2]);
		int x=dis(temp2);int y=dis(temp);
		if(x==INT_MAX&&y==INT_MAX){
			swap(temp2[nop1],temp2[nop2]);
			temper*=0.99;
			continue;
		}
		re_value=min(re_value,min(x,y));
		if(O_K(x-y,temper)){
			swap(temp[nop1],temp[nop2]);
		}else{
			swap(temp2[nop1],temp2[nop2]);
		}
		temper*=0.99;
	}
	return re_value;
}
int main(){
	srand(time(NULL));
	n=read();int m=read();
	rep(i,1,n){
		rep(j,1,n){
			if(i==j)maps[i][j]=0;
			maps[i][j]=INT_MAX;
		}
		temp[i]=i;temp2[i]=i;
	}
	rep(i,1,m){
		int u=read();int v=read();int w=read();
		maps[u][v]=min(maps[u][v],w);
		maps[v][u]=maps[u][v];
	}
	
	int T=350;int ans=INT_MAX;
	while(T){
		T--;
		ans=min(ans,solve());
	}
	write(ans);
	return 0;
}

本程序不知为何,在UOJ上只有97,被Extra Test 7卡WA了

(欢迎大佬提供改进意见)

相关标签: NOIP