#include #include using namespace std; long double ENG(int x1,int y1, int x2, int y2,int t){ long double uq= sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); return uq*uq*t; } long SCORE(long long s){ return (long)(1000000000/(1000+(long)sqrt(s))); } struct unionfind{ //par=親 siz=グループの頂点数 vectorpar,siz; unionfind(int n):par(n,-1),siz(n,1){} //根を求める int root(int x){ if(par[x]==-1)return x; else return par[x]=root(par[x]); } //xとyが同グループか(根が同じか) bool issame(int x,int y){ return root(x)==root(y); } //xを含むグループとyを含むグループを併合する bool unite(int x,int y){ x=root(x),y=root(y); if(x==y)return false; //y側のサイズが小さくなるようにする if(siz[x]> 19)) ^ (t ^ (t >> 8)); } static double rand01(){//ランダム数(0.0以上1.0未満の小数) return(randxor()+0.5)*(1.0/UINT_MAX); } double time_limit=950; double gettime; chrono::system_clock::time_point time_now; chrono::system_clock::time_point time_start = chrono::system_clock::now(); double start_temp=500, end_temp=0.001,temp; int main(){ int n,m; cin>>n>>m; vectora(n),b(n); for(int i=0; i>a[i]>>b[i]; } // vector>eng_all; vector>>eng(100,vector>(100)); vector>>eng_sr(100,vector>(100)); for(int i=0;i<100;i++){ for(int j=0;j<100;j++){ if(i!=j){ // eng_all.emplace_back(eu2(a[i],b[i],a[j],b[j]),j); eng[i][j]=make_pair(ENG(a[i],b[i],a[j],b[j],25),j); eng_sr[i][j]=eng[i][j]; } else{ eng[i][j]=make_pair(1000000000001,-1); eng_sr[i][j]=eng[i][j]; } } sort(eng_sr[i].begin(),eng_sr[i].end()); } vector>cd(8);//ロボてりーの位置 ×8 for(int i=0; i<8; i++){ cd[i].first=0; cd[i].second=0; } vector>tr,tr_best; bitset<100>visited; int now=0; visited[now]=true; tr.emplace_back(1,0); while(true){ bool jdg=false; for(int i=0; i<99; i++){ if(!(visited[eng_sr[now][i].second])){ int next=eng_sr[now][i].second; tr.emplace_back(1,next); now=next; visited[next]=true; jdg=true; break; } } if(!jdg)break; } tr.emplace_back(1,0); long double eng_sum=0; for(int i=0; i<100; i++){ eng_sum+=(long double)eng[tr[i].second][tr[i+1].second].first; } long score,score_best; score=SCORE(eng_sum); score_best=score; tr_best=tr; long double cnt=0,cnt_p1=0,cnt_p2=0,cnt_rec; while(gettime(time_now-time_start).count(); temp=start_temp+(end_temp-start_temp)*gettime/time_limit; } int A=randxor()%99+1, B=randxor()%99+1; int na=tr[A-1].second,a=tr[A].second,an=tr[A+1].second; int nb=tr[B-1].second,b=tr[B].second,bn=tr[B+1].second; int eng_m=(int)(eng[na][a].first+eng[a][an].first+eng[nb][b].first+eng[b][bn].first); int eng_p=(int)(eng[na][b].first+eng[b][an].first+eng[nb][a].first+eng[a][bn].first); int score_r=SCORE(eng_sum-eng_m+eng_p); double prob=exp((score_r-score)/temp); double rnd_d=rand01(); bool judge=false; if(prob>rnd_d){ tr[A].second=b,tr[B].second=a; eng_sum=eng_sum-eng_m+eng_p; score=score_r; if(score>score_best){ tr_best=tr; score_best=score; } if(gettime<475)cnt_p1++; else cnt_p2++; } cnt++; } for(auto x:cd){ cout<>g(100,vector()); unionfind uf(n); for(int i=0; i(eng_all[i]),U=get<1>(eng_all[i]),V=get<2>(eng_all[i]); if(!uf.issame(U,V)){ uf.unite(U,V); g[U].push_back(V); g[V].push_back(U); } } */ /* ◇要素数の多い配列は pairを使う 呼び出し:get<0>(変数名) ◇vectorは bitsetを使う bitの並びでtrue/falseを設定できる 宣言 bitset<5> 変数名; 変更 bit[0]=true; 出力 cout<< bit[0]<>に要素を追加するときは emplace_back を使う pairの要素を追加 変数名.emplace_back(1,2); make_pairは不要 ◇set> なら emplace を使う pairの要素を追加 変数名.emplace(1,2); */