結果
| 問題 |
No.5007 Steiner Space Travel
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-07-30 17:49:14 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 603 ms / 1,000 ms |
| コード長 | 4,324 bytes |
| コンパイル時間 | 2,136 ms |
| 実行使用メモリ | 6,952 KB |
| スコア | 6,736,781 |
| 最終ジャッジ日時 | 2022-07-30 17:49:46 |
| 合計ジャッジ時間 | 22,377 ms |
|
ジャッジサーバーID (参考情報) |
judge16 / judge10 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 30 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for (int i=0;i<(int)(n);i++)
int fr(pair<int,int> &a,pair<int,int> &b){
return (a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second);
}
pair<int,int> MKsn(pair<int,int> &a,pair<int,int> &b){
return make_pair((a.first+b.first)/2,(a.second+b.second)/2);
}
unsigned int randxor(){
static unsigned int x=123456789,y=362436069,z=521288629,w=88675123;
unsigned int t=(x^(x<<11)); x=y;y=z;z=w;
return( w=(w^(w>>19))^(t^(t>>8)) );
}
vector<vector<ll>> d(110,vector<ll>(110,0));
vector<pair<int,int>> v(110);
ll cost_calc(vector<pair<int,int>> &ans,vector<pair<int,int>> &ccd){
double cost=0;
int flg=0;
int bf=-1;
for(auto [x,i]:ans){
if(bf!=-1){
if(x==1){
if(flg){
cost+=fr(v.at(i),ccd.at(bf))*5;
flg=0;
}
else cost+=d.at(bf).at(i)*25;
}else{
if(flg) cost+=fr(ccd.at(i),ccd.at(bf));
else{
cost+=fr(ccd.at(i),v.at(bf))*5;
flg=1;
}
}
}
bf=i;
}
return round(1e9/(1000+sqrt(cost)));
}
ll Scost_calc(vector<pair<int,int>> &ans){
double cost=0;
int bf=-1;
for(auto [x,i]:ans){
if(bf!=-1){
cost+=d.at(bf).at(i)*25;
}
bf=i;
}
return round(1e9/(1000+sqrt(cost)));
}
int main(){
auto start_time = std::chrono::system_clock::now();
ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n,m;
cin>>n>>m;
vector<pair<int,int>> v(n);
rep(i,n){
cin>>v.at(i).first>>v.at(i).second;
}
rep(i,n){
for(int j=i+1;j<n;j++){
d.at(i).at(j)=fr(v.at(i),v.at(j));
d.at(j).at(i)=d.at(i).at(j);
}
}
vector<bool> stl(n,0);
vector<pair<int,int>> ccd(m,{0,0});
vector<pair<int,int>> ans;
ans.emplace_back(1,0);
stl.at(0)=1;
int nw=0;
rep(i,n-1){
int mn=1e9;
int mnct=-1;
rep(j,n){
if(stl.at(j)) continue;
if(mn>d.at(nw).at(j)){
mn=d.at(nw).at(j);
mnct=j;
}
}
if(mnct==-1){
break;
}
stl.at(mnct)=1;
ans.emplace_back(1,mnct);
nw=mnct;
}
ans.emplace_back(1,0);
ll nwcost=Scost_calc(ans);
const unsigned int inf=-1;
const double start_temp=10;
const double end_temp=0;
const int lim_time=100;
int sz=ans.size();
while(1){
int w_time=chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now()-start_time).count();
if(w_time>lim_time){
break;
}
int a=0,b=0;
while(a==0||a==sz-1) a=randxor()%sz;
while(b==0||b==sz-1||b==a) b=randxor()%sz;
swap(ans.at(a),ans.at(b));
ll nxcost=Scost_calc(ans);
double temp=start_temp+(end_temp-start_temp)*w_time/lim_time;
double prob=exp(double(nxcost-nwcost)/temp);
if(prob>double(randxor())/double(inf)) nwcost=nxcost;
else swap(ans.at(a),ans.at(b));
}
const double start_temp2=500;
const double end_temp2=0;
const int lim_time2=500;
while(1){
int w_time=chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now()-start_time).count();
w_time-=lim_time;
if(w_time>lim_time2){
break;
}
int a=0,b=0;
while(a==0||a==sz-1) a=randxor()%sz;
while(b==0||b==sz-1||b==a) b=randxor()%sz;
vector<pair<int,int>> nans;
if(a>b) swap(a,b);
for(int i=0;i<a;i++) nans.emplace_back(ans.at(i));
for(int i=b-1;i>=a;i--) nans.emplace_back(ans.at(i));
for(int i=b;i<sz;i++) nans.emplace_back(ans.at(i));
ll nxcost=Scost_calc(nans);
double temp=start_temp2+(end_temp2-start_temp2)*w_time/lim_time2;
double prob=exp(double(nxcost-nwcost)/temp);
if(prob>double(randxor())/double(inf)) {
nwcost=nxcost;
ans=nans;
}
}
priority_queue<pair<ll,int>> pq;
rep(i,sz-1){
pq.emplace(d.at(ans.at(i).second).at(ans.at(i+1).second),i);
}
vector<int> mm(m,-1);
rep(i,m){
int a=pq.top().second;
pq.pop();
mm.at(i)=a;
ccd.at(i)=MKsn(v.at(ans.at(a).second),v.at(ans.at(a+1).second));
}
vector<pair<int,int>> nans;
int ct=0;
rep(i,sz){
nans.emplace_back(ans.at(i));
if(ct<m&&mm.at(ct)==i){
nans.emplace_back(2,ct);
ct++;
}
}
ans=nans;
for(auto ccdd:ccd){
cout<<ccdd.first<<" "<<ccdd.second<<"\n";
}
cout<<ans.size()<<"\n";
for(auto a:ans){
cout<<a.first<<" "<<a.second+1<<"\n";
}
}