#include using namespace std; #include using namespace atcoder; using ll=long long; using Graph=vector>; #define INF 1000000000 #define MOD 998244353 #define MAX 500 int N,M; int alpha = 5; random_device seed; mt19937 engine(seed()); uniform_real_distribution<> uniform_real_dist(0.0,1.0); clock_t start_t,end_t; double elapsed_time; //実行制限時間-ε double time_limit=0.18; //初期温度 int annCnt=0; int loopCnt=5; double T0[5] = {1e6,1e5,1e4,1e3,1e2}; //double T0=1e6; //最終温度 double T1=1e1; void two_opt(vector &path, vector> &dist, int &S) { start_t=clock(); int n=path.size(); end_t=clock(); elapsed_time=(double)(end_t-start_t)/CLOCKS_PER_SEC; // path[1, n-2]の順番を変更 while (elapsed_time <= time_limit) { double T=pow(T0[annCnt],1.0-elapsed_time/time_limit)*pow(T1,elapsed_time/time_limit); int left = rand()%(n-2) + 1; int right = rand()%(n-2) + 1; if (left == right) { continue; } if (right < left) { swap(left, right); } int deltaS = 0.0; deltaS -= dist[path[left-1]][path[left]] + dist[path[right]][path[right+1]]; deltaS += dist[path[left-1]][path[right]] + dist[path[left]][path[right+1]]; int diff = round(1.0e9/(1.0e3 + sqrt(S+deltaS))) - round(1.0e9/(1.0e3 + sqrt(S))); //遷移確率 double p=min(1.0,exp(diff/T)); if(uniform_real_dist(engine)<=p){ S += deltaS; reverse(path.begin() + left, path.begin() + (right+1)); } end_t=clock(); elapsed_time=(double)(end_t-start_t)/CLOCKS_PER_SEC; } annCnt++; } void update_base_place(vector &ans,vector &a,vector &b,vector &x,vector &y,vector> &dist,vector> &nextNode) { // 基地の位置を変更 vector pathCnt(M,0); for(int i=0;i=N){ int v=ans[i+1]-N; int u=ans[i]; pathCnt[v]++; x[v]+=a[u]; y[v]+=b[u]; } else if(ans[i]>=N&&ans[i+1]0){ x[i]/=pathCnt[i]; y[i]/=pathCnt[i]; } else{ x[i]=rand()%1000; y[i]=rand()%1000; } } // distテーブルの更新 for(int i=0;i solve_ans(vector &path,vector> &nextNode) { vector ans; ans.push_back(path[0]); for(int i=0;i<(int)path.size()-1;i++){ int v=path[i]; while(v!=path[i+1]){ v=nextNode[v][path[i+1]]; ans.push_back(v); } } return ans; } int main(){ cin>>N>>M; vector a(N), b(N); for(int i=0;i>a[i]>>b[i]; } /* vector> planetCnt(N); for(int i=0;i x(M),y(M); int k=0; for(int i=N-1;i>=0;i--){ bool flag=true; for(int j=0;j x={500+delta, 500+delta, 500, 500-delta, 500-delta, 500-delta, 500, 500+delta}; vector y={500, 500+delta, 500+delta, 500+delta, 500, 500-delta, 500-delta, 500-delta}; vector> dist(N+M,vector(N+M,INF)); vector> nextNode(N+M,vector(N+M)); for(int i=0;i> nearbyPlanets(M); int currentBase; for(int i=0;i path; path.push_back(0); for(int i=0;i ans = solve_ans(path,nextNode); // 基地の位置を変更 update_base_place(ans,a,b,x,y,dist,nextNode); //経路再計算 ans=solve_ans(path,nextNode); if(ii==loopCnt-1){ // 出力 for(int i=0;i