#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using vec_int = vector; using P = pair; using T = tuple; using ll = long long; // using PQ = priority_queue, vector>, greater>>; #define rep(i, n) for (int i = 0; i < (int)(n); i++) float initial_T = 5000; float final_T = 1000; float TIME_LIMIT = 1000; float TIME_LIMIT_STATION = 10; int RAND_ARR_LEN = 100000; int RAND_RANGE = 1000000000; vector

DIRS = {make_pair(0, -1), make_pair(-1, 0), make_pair(0, 1), make_pair(1, 0)}; bool is_in(int x, int y, int N) { if (x >= 0 && x < N && y >= 0 && y < N) return true; return false; } // std::mt19937 mt{ std::random_device{}() }; std::mt19937 mt{12345}; std::uniform_int_distribution dist(1, RAND_RANGE); float get_time(bool init) { static std::chrono::system_clock::time_point start; if (init) { start = std::chrono::system_clock::now(); } std::chrono::system_clock::time_point end = std::chrono::system_clock::now(); return std::chrono::duration_cast(end - start).count(); //処理に要した時間をミリ秒に変換 } class Rand { private: int count = 0; vec_int rand_arr; public: Rand(){ rep(i, RAND_ARR_LEN){ rand_arr.push_back(dist(mt)); } } ; int get(); int get_rand(int from, int to); float get_float(); } ; int Rand::get() { int num = rand_arr.at(count); count += 1; count %= RAND_ARR_LEN; return num; } int Rand::get_rand(int from, int to) { int diff = to - from; int num = get() % diff; return num + from; } float Rand::get_float() { // 0~1の間の一様乱数 return (float)get() / (float)RAND_RANGE; } Rand ro; float current_tmp_station(float current_time) { return final_T + (initial_T - final_T) * (TIME_LIMIT_STATION - current_time) / TIME_LIMIT_STATION; } bool is_valid_transition_station(int diff, float current_time) { float t = current_tmp_station(current_time); float rand = ro.get_float(); // cerr<<"tmperature"< &stations, vec_int &excluded){ int result = 0; rep(i, N){ if(excluded.at(i)==1)continue; int tmp_dist = INT_MAX; rep(j, M){ tmp_dist = min(tmp_dist, stations.at(j).square_distance(a.at(i), b.at(i))); } result += tmp_dist; } return result; } void cout_ans(vector

&ans){ cout<>>> make_dist_map(vector &stations){ vector>>> result(N, vector>>(N+M)); vector> visited(N, vec_int(N+M, 0)); for(int i=0;i, greater> pq; pq.emplace(0, i, -1); while(!pq.empty()){ int dist, pos, prev; tie(dist, pos, prev) = pq.top(); pq.pop(); if(visited.at(i).at(pos)==1)continue; if(pos route; if(prev!=-1){ route = result.at(i).at(prev).second; } route.push_back(make_pair(1, pos)); result.at(i).at(pos) = make_pair(dist, route); vector

route2 = route; reverse(route2.begin(), route2.end()); result.at(pos).at(i) = make_pair(dist, route2); for(int j=0;j route; if(prev!=-1){ route = result.at(i).at(prev).second; } route.push_back(make_pair(2, pos-N)); result.at(i).at(pos) = make_pair(dist, route); for(int j=0;j &stations, vector

&tmp_ans){ int result = 0; for(int i=1;i &ans, vector &stations, vector>>> &dist_mat){ // 訪れていない場所の中で一番コストが小さくいけそうなところにいく int result = 0; int pos = 0; ans.push_back(make_pair(1, 0)); vec_int visited(N, 0); while(true){ visited.at(pos) = 1; int min_dist = INT_MAX; int next_pos = -1; for(int i=0;itmp_dist){ min_dist = tmp_dist; next_pos = i; } } if(next_pos==-1)break; int tmp_dist2 = calc_dist(stations, ans); for(auto p_pos: dist_mat.at(pos).at(next_pos).second){ // if(p_pos.second == pos&&p_pos.first==1)continue; if(ans.at(ans.size()-1)==p_pos)continue; ans.push_back(p_pos); } int tmp_dist3 = calc_dist(stations, ans); pos = next_pos; result += min_dist; } for(auto p_pos: dist_mat.at(pos).at(0).second){ ans.push_back(p_pos); } result += dist_mat.at(pos).at(0).first; return result; } void adjust_station_pos(vector &stations, vector

&tmp_ans){ vector station_connections(M); rep(i, tmp_ans.size()){ if(tmp_ans.at(i).first==2){ int st = tmp_ans.at(i).second; if(tmp_ans.at(i-1).first==1){ station_connections.at(st).push_back(tmp_ans.at(i-1).second); } if(tmp_ans.at(i+1).first==1){ station_connections.at(st).push_back(tmp_ans.at(i+1).second); } } } for(int station = 0;station>N>>M; rep(i, N){ int aa, bb; cin>>aa>>bb; a.push_back(aa); b.push_back(bb); } vector dist_vec; rep(i, N){ for(int j=i+1;j ans; vector ans_stations; while(get_time(false) excluded(N, 0); for(int i=0;i stations(M); rep(i, M){ stations.at(i) = SpaceStation(ro.get_rand(0, 1001), ro.get_rand(0, 1001)); } int station_score = tot_distance(stations, excluded); cerr<<"initial tot square distance:"<TIME_LIMIT_STATION)break; int selected_station = ro.get_rand(0, M); int old_x = stations.at(selected_station).x; int old_y = stations.at(selected_station).y; stations.at(selected_station).random_move(); int new_score = tot_distance(stations, excluded); int diff = new_score-station_score; if(is_valid_transition_station(-1*diff, ct)){//小さくなる方がいい station_score = new_score; }else{ stations.at(selected_station).set_pos(old_x, old_y); } } cerr<<"annealed tot square distance:"<>>> dist = make_dist_map(stations); cerr<<"time2:"< tmp_ans; int tmp_dist = greedy_strategy(tmp_ans, stations, dist); cerr<<"tmp_dist1"<