模拟退火求调
查看原帖
模拟退火求调
473188
NaHCO3_tht楼主2023/10/10 18:27
/*
by tanhaotian
*/
#include <bits/stdc++.h>
#define f_inline inline __attribute__((always_inline))
#define ll long long
using namespace std;
const int maxn = 1e5+5;
const double eps = 1e-9;
namespace quick{
	f_inline int read(){
		int x;
		char c=getchar();x=0;int f=0;
		for(;!isdigit(c);c=getchar()) f|=(c=='-');
		for(;isdigit(c);c=getchar()) x=((x<<3)+(x<<1)+(c^48));
		return x=f?-x:x;
	}
	f_inline ll _read(){
		ll x;
		char c=getchar();x=0;int f=0;
		for(;!isdigit(c);c=getchar()) f|=(c=='-');
		for(;isdigit(c);c=getchar()) x=((x<<3)+(x<<1)+(c^48));
		return x=f?-x:x;
	}
	template< typename T >inline void write(T x){
		if(x<0) putchar('-'),x=-x;
		if(x>9) write(x/10);
		putchar(x%10^48);
	}
	template< typename T >inline void print(T x){
		write(x);putchar('\n');
	}
	template< typename T >inline void _print(T x){
		write(x);putchar(' ');
	}
	inline void swap(int &a,int &b){a^=b,b^=a,a^=b;}
	inline int max(const int &a,const int &b){return a>b?a:b;}
	inline int min(const int &a,const int &b){return a<b?a:b;}
	inline ll labs(ll x){return x>0?x:-x;}
}
using namespace quick;
int n;
int x[maxn],y[maxn];
ll dis[maxn];
ll ansind;
ll ans;
f_inline int abs(int x){return x>0?x:-x;}
f_inline ll gdis(int a1,int b1,int a2,int b2){
	return max(abs(a1-a2),abs(b1-b2));
}
f_inline ll calc(int a,int b){
	ll res = 0;
	for(register int i(1);i <= n;++i){
		res += gdis(a,b,x[i],y[i]);
	}
	return res;
}
f_inline void SA(){
	const double dt = (n <= 2e4?0.9964:0.99417);
	double T = 50;
	while(T > eps){
		register int tind = rand()%n+1;
		register ll tmp;
		if(dis[tind] != -1){
			T *= dt;
			continue;
		}
		else tmp = calc(x[tind],y[tind]),dis[tind] = tmp;
		int del = tmp-ans;
		if(tmp < ans){
			ansind = tind,ans = tmp;
		}else if(exp(-del/T) > rand()){
			ansind = tind;
		}
		T *= dt;
	}
}
signed main(){
//	freopen("squ.in","r",stdin);
//	freopen("squ.out","w",stdout);
	srand(time(0));
	n = read();
	memset(dis,-1,sizeof(dis));
	for(register int i(1);i <= n;++i){
		x[i] = read(),y[i] = read();
	}
	ansind = rand()%n+1;
	ans = calc(x[ansind],y[ansind]);
	while(clock() < 0.8*CLOCKS_PER_SEC){
		SA();
	}
	cout<<ans;
	return 0;
}
2023/10/10 18:27
加载中...