Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <set>
- #include <algorithm>
- #include <math.h>
- #include <float.h>
- double dist(const std::pair<int64_t, int64_t>& p1, const std::pair<int64_t, int64_t>& p2) {
- return std::sqrt((p1.first - p2.first) * (p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second));
- }
- int skip(int i, int N) {
- if ((i + 1) == N) {
- return 0;
- } else {
- return i + 1;
- }
- }
- int bskip(int i, int N) {
- if ((i - 1) == -1) {
- return N - 1;
- } else {
- return i - 1;
- }
- }
- void swap_pairs(int N, std::vector<int>& path, const std::vector<std::vector<double>>& len) {
- int begin = 0, end = 1, prev = N - 1, next = 2, count = 0;
- while (true) {
- double old_len = len[path[prev]][path[begin]] + len[path[begin]][path[end]] + len[path[end]][path[next]];
- double new_len = len[path[prev]][path[end]] + len[path[begin]][path[end]] + len[path[begin]][path[next]];
- if (old_len > new_len) {
- count += 1;
- std::swap(path[begin], path[end]);
- }
- prev = begin;
- begin = end;
- end = next;
- next++;
- if (next == N) {
- next = 0;
- }
- if (begin == 0) {
- if (count == 0) {
- break;
- }
- count = 0;
- }
- }
- }
- void swap_two(int N, std::vector<int>& path, const std::vector<std::vector<double>>& len) {
- for (int i = 0; i < N; ++i) {
- int begin1 = i;
- int begin2 = skip(skip(i, N), N);
- int count = 0;
- while (true) {
- if (skip(begin2, N) == begin1) {
- if (count == 0) {
- break;Плейлисты
- }
- begin2 = skip(skip(i, N), N);
- count = 0;
- } else {
- if (skip(skip(begin1, N), N) == begin2) {
- double old_len = len[path[begin1]][path[skip(begin1, N)]] + len[path[begin2]][path[skip(begin2, N)]];
- double new_len = len[path[begin1]][path[begin2]] + len[path[skip(begin1, N)]][path[skip(begin2, N)]];
- if (old_len > new_len) {
- count += 1;
- std::swap(path[begin2], path[skip(begin1, N)]);
- }
- begin2 = skip(begin2, N);
- } else {
- double old_len = len[path[begin1]][path[skip(begin1, N)]] + len[path[begin2]][path[skip(begin2, N)]] +
- len[path[skip(begin1, N)]][path[skip(skip(begin1, N), N)]] + len[path[begin2]][path[bskip(begin2, N)]];
- double new_len = len[path[begin1]][path[begin2]] + len[path[skip(begin1, N)]][path[skip(begin2, N)]] +
- len[path[begin2]][path[skip(skip(begin1, N), N)]] + len[path[skip(begin1, N)]][path[bskip(begin2, N)]];
- if (old_len > new_len) {
- count += 1;
- std::swap(path[begin2], path[skip(begin1, N)]);
- }
- begin2 = skip(begin2, N);
- }
- }
- }
- }
- }
- void permutation(int N, std::vector<int>& path, const std::vector<std::vector<double>>& len) {
- }
- void print_correct(const std::vector<int>& path) {
- int first;
- for (int i = 0; i < path.size(); ++i) {
- if (path[i] == 0) {
- first = i;
- break;
- }
- }
- for (int i = first; i < path.size(); ++i) {
- std::cout << path[i] + 1 << ' ';
- }
- for (int i = 0; i < first; ++i) {
- std::cout << path[i] + 1 << ' ';
- }
- std::cout << path[first] + 1 << '\n';
- }
- int main() {
- int N, a, b;
- std::cin >> N;
- std::vector<std::pair<int64_t, int64_t>> points(N);
- for (int i = 0; i < N; ++i) {
- std::cin >> a >> b;
- points[i] = std::make_pair(a, b);
- }
- std::vector<std::vector<double>> len(N);
- for (auto& i : len) {
- i.resize(N);
- }
- for (int i = 0; i < N; ++i) {
- for (int j = i + 1; j < N; ++j) {
- double d = dist(points[i], points[j]);
- len[i][j] = d;
- len[j][i] = d;
- }
- }
- std::set<int> used;
- std::vector<int> path(N);
- path[0] = 0;
- used.insert(0);
- int64_t dist_result = 0;
- for (int i = 0; i < N - 1; ++i) {
- int best = i + 1;
- double best_dist = DBL_MAX;
- for (int j = 0; j < N; ++j) {
- if (path[i] != j) {
- if (used.find(j) == used.end()) {
- double dist_temp = len[path[i]][j];
- if (dist_temp < best_dist) {
- best = j;
- best_dist = dist_temp;
- }
- }
- }
- }
- used.insert(best);
- path[i + 1] = best;
- dist_result += best_dist;
- }
- dist_result += len[0][N - 1];
- // for (auto i : path) {
- // std::cout << i + 1 << ' ';
- // }
- // std::cout << path[0] + 1 << '\n';
- swap_pairs(N, path, len);
- swap_two(N, path, len);
- // for (auto i : path) {
- // std::cout << i + 1 << ' ';
- // }
- // std::cout << path[0] + 1 << '\n';
- print_correct(path);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement