#ifdef LOCAL #define _GLIBCXX_DEBUG #endif #include using namespace std; using ll = long long; using ull = unsigned long long; using ld = long double; void solve_test(istream &cin, ostream &cout) { int n; cin >> n; vector x(n), y(n); for (int i = 0; i < n; i++) cin >> x[i] >> y[i]; vector> dist(n, vector(n)); for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { const int dx = x[i] - x[j], dy = y[i] - y[j]; dist[i][j] = sqrtl((ll) dx * dx + (ll) dy * dy); } ld best = 1e100; vector where; auto score = [&] (const vector &p) { ld cur = 0; for (int i = 0; i + 1 < n; i++) cur += dist[p[i]][p[i + 1]]; return cur; }; auto work = [&](const vector &p) { const ld cur = score(p); if (best > cur) { best = cur; where = p; } }; mt19937 rng; ld average_score_delta = 0; const int iters = 100; for (int it = 0; it < iters; it++) { const int l = rng() % n; const int i = rng() % n; const int j = rng() % n; average_score_delta += abs(dist[l][i] - dist[l][j]); } average_score_delta /= iters; average_score_delta *= 2; vector p(n); iota(p.begin(), p.end(), 0); #ifndef LOCAL if (n <= 10) { do { work(p); } while (next_permutation(p.begin(), p.end())); } else #endif { while (clock() / (double)CLOCKS_PER_SEC < 1.7) { shuffle(p.begin(), p.end(), rng); uniform_real_distribution distr_rand(0, 1); work(p); ld cur = score(p); ld t = average_score_delta; const ld t_min = average_score_delta * 0.1; const ld t_mult = 0.9999; while (t >= t_min) { if (best > cur) { best = cur; where = p; } const int r = rng() % n + 1; const int l = rng() % r; ld diff = 0; if (l > 0) { diff -= dist[p[l - 1]][p[l]]; diff += dist[p[l - 1]][p[r - 1]]; } if (r + 1 < n) { diff -= dist[p[r - 1]][p[r]]; diff += dist[p[l]][p[r]]; } if (diff < 0 || distr_rand(rng) < exp(-diff / t)) { cur += diff; reverse(p.begin() + l, p.begin() + r); } t *= t_mult; } } } for (const int it : where) cout << it + 1 << " "; cout << endl; } void solve(istream &cin = std::cin, ostream &cout = std::cout) { solve_test(cin, cout); } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout << fixed; #ifdef LOCAL auto st = clock(); ifstream fin("../input.txt"); do { solve(fin); cout << "===" << endl; string str; while (getline(fin, str) && str != string(max(1, (int) str.size()), '=')); } while (fin); cout << setprecision(6) << "clock: " << double(clock() - st) / CLOCKS_PER_SEC << endl; #else solve(); #endif return 0; }