"""2-opt and Or-opt in turn, until neither shortens the tour. Or-opt moves a run of one to three cities, either way round, to the place in the tour where it adds the least.""" import json import math import sys p = json.load(sys.stdin) n = len(p) def d(i, j): return math.dist(p[i], p[j]) def two_opt(t): moved, better = False, True while better: better = False for i in range(1, n - 1): for j in range(i + 1, n): a, b, c, e = t[i - 1], t[i], t[j], t[(j + 1) % n] if d(a, c) + d(b, e) < d(a, b) + d(c, e) - 1e-12: t[i:j + 1] = reversed(t[i:j + 1]) better = moved = True return moved def or_opt(t): for k in (1, 2, 3): for i in range(1, n - k): run = t[i:i + k] a, b = t[i - 1], t[(i + k) % n] saved = d(a, run[0]) + d(run[-1], b) - d(a, b) rest = t[:i] + t[i + k:] for j in range(1, len(rest) + 1): x, y = rest[j - 1], rest[j % len(rest)] for r in (run, run[::-1]): if d(x, r[0]) + d(r[-1], y) - d(x, y) < saved - 1e-12: t[:] = rest[:j] + r + rest[j:] return True return False left, tour = set(range(1, n)), [0] while left: nxt = min(left, key=lambda j: d(tour[-1], j)) left.remove(nxt) tour.append(nxt) two_opt(tour) while or_opt(tour): two_opt(tour) print(json.dumps(tour))