from itertools import permutations import sys from time import time from random import random, randrange, choice, choices, randint from heapq import heappop, heappush from math import exp START = time() INF=10**9 def get_time(START): return time() - START def dist(p1,p2): x1,y1=p1 x2,y2=p2 return (x1-x2)**2 + (y1-y2)**2 def dist2(p1,p2): return Ecost[p1][p2] def cost(i: int, j: int): d = dist(Terminals[i], Terminals[j]) if i 0: tour = reverse_path(tour, i, j-1) improve = True return tour def three_opt(tour): n = len(tour) improve = True while improve: improve = False for i in range(1, n-2): for j in range(i+1, n-1): for k in range(j+1, n): if i == 1 and k == n-1: continue delta = calc_delta(tour, i, j, k) if delta < 0: tour = reverse_path(tour, i, j-1) tour = reverse_path(tour, j, k-1) tour = reverse_path(tour, i, k-1) improve = True return tour def two_opt_rand(tour): n = len(tour) a,b=randint(1,n-1),randint(1,n-1) while a==b or (a == 1 and b == n-1) or (b == 1 and a == n-1): a,b=randint(1,n-1),randint(1,n-1) if a>b: a,b=b,a delta = calc_delta_two(tour, a, b) if delta > 0: tour = reverse_path(tour, a, b-1) return tour def three_opt(tour): n = len(tour) improve = True while improve: improve = False for i in range(1, n-2): for j in range(i+1, n-1): for k in range(j+1, n): if i == 1 and k == n-1: continue delta = calc_delta(tour, i, j, k) if delta < 0: tour = reverse_path(tour, i, j-1) tour = reverse_path(tour, j, k-1) tour = reverse_path(tour, i, k-1) improve = True return tour def calc_delta_two(tour, i, j): a, b, c, d = tour[i-1], tour[i], tour[j-1], tour[j%len(tour)] return (dist2(a,b) + dist2(c,d)) - (dist2(a,c) + dist2(b,d)) def calc_delta(tour, i, j, k): a, b, c, d, e, f = tour[i-1], tour[i], tour[j-1], tour[j], tour[k-1], tour[k%len(tour)] return (dist2(a,b) + dist2(c,d) + dist2(e,f)) - (dist2(a,d) + dist2(c,e) + dist2(b,f)) def reverse_path(tour, i, j): return tour[:i] + tour[i:j+1][::-1] + tour[j+1:] # インプット N,M=map(int,input().split()) Terminals = [tuple(map(int,input().split())) for _ in range(N)] KM=KMEANS() KM.Clustering(Terminals,M) Stations = KM.reps[:] # print(Stations,file= sys.stderr) Terminals += Stations T=len(Terminals) #各Terminalの移動コストをワーシャルフロイトで計算 Ecost=[[INF]*T for i in range(T)] for i,t1 in enumerate(Terminals): for j,t2 in enumerate(Terminals): Ecost[i][j]=cost(i,j) #ワーシャルフロイト for k in range(T): for i in range(T): for j in range(T): Ecost[i][j]=min(Ecost[i][j],Ecost[i][k]+Ecost[k][j]) #ステーションを回る順序を全探索で決定 #ステーション毎に貪欲に回る順序を決定 StationCluster=[[] for i in range(M)] TerminalsStation=[0]*N for i in range(N): best_dist=INF best_st=-1 for j in range(M): d = dist(Terminals[i],Terminals[j+N]) if d=TerminalsStation[0]:s+=1 station_list.append(s+N) station_list.append(TerminalsStation[0]+N) d = calc_score2(station_list) if d