結果
問題 | No.5007 Steiner Space Travel |
ユーザー | terry_u16 |
提出日時 | 2022-06-30 02:06:36 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 334 ms / 1,000 ms |
コード長 | 3,849 bytes |
コンパイル時間 | 265 ms |
実行使用メモリ | 84,448 KB |
スコア | 7,620,588 |
最終ジャッジ日時 | 2022-07-30 13:31:43 |
合計ジャッジ時間 | 11,610 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge14 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 306 ms
83,524 KB |
testcase_01 | AC | 298 ms
84,448 KB |
testcase_02 | AC | 300 ms
84,412 KB |
testcase_03 | AC | 309 ms
84,180 KB |
testcase_04 | AC | 317 ms
83,372 KB |
testcase_05 | AC | 312 ms
83,760 KB |
testcase_06 | AC | 310 ms
84,020 KB |
testcase_07 | AC | 303 ms
83,864 KB |
testcase_08 | AC | 303 ms
84,236 KB |
testcase_09 | AC | 308 ms
84,128 KB |
testcase_10 | AC | 302 ms
83,540 KB |
testcase_11 | AC | 326 ms
83,304 KB |
testcase_12 | AC | 316 ms
83,268 KB |
testcase_13 | AC | 311 ms
84,220 KB |
testcase_14 | AC | 298 ms
84,008 KB |
testcase_15 | AC | 318 ms
83,904 KB |
testcase_16 | AC | 295 ms
84,100 KB |
testcase_17 | AC | 304 ms
83,656 KB |
testcase_18 | AC | 300 ms
83,424 KB |
testcase_19 | AC | 301 ms
84,140 KB |
testcase_20 | AC | 305 ms
83,272 KB |
testcase_21 | AC | 295 ms
83,708 KB |
testcase_22 | AC | 307 ms
84,072 KB |
testcase_23 | AC | 305 ms
83,960 KB |
testcase_24 | AC | 334 ms
84,208 KB |
testcase_25 | AC | 313 ms
83,668 KB |
testcase_26 | AC | 289 ms
83,480 KB |
testcase_27 | AC | 321 ms
84,076 KB |
testcase_28 | AC | 300 ms
83,984 KB |
testcase_29 | AC | 291 ms
84,144 KB |
ソースコード
import heapq INF = 1000000000 # ======================== # 入力読み込み # ======================== n, m = map(int, input().split()) # 各経由地の座標 points = [] for _ in range(n): x, y = map(int, input().split()) points.append((x, y)) # 宇宙ステーションの座標は適当に決め打ち # # x x x # x x # x x x # # みたいにする points.append((300, 300)) points.append((300, 500)) points.append((300, 700)) points.append((500, 300)) points.append((500, 700)) points.append((700, 300)) points.append((700, 500)) points.append((700, 700)) # ======================== # ワーシャルフロイド # ======================== def calc_energy(i, j): """ 2点間の消費エネルギーを計算する関数 """ x1, y1 = points[i] x2, y2 = points[j] dx = x1 - x2 dy = y1 - y2 energy = dx * dx + dy * dy # 惑星かどうかは i < n で判定可能 if i < n: energy *= 5 if j < n: energy *= 5 return energy distances = [[0] * len(points) for _ in range(len(points))] # 全点間エネルギーを計算 for i in range(len(points)): for j in range(len(points)): distances[i][j] = calc_energy(i, j) # ワーシャルフロイド for k in range(len(points)): for i in range(len(points)): for j in range(len(points)): d = distances[i][k] + distances[k][j] distances[i][j] = min(distances[i][j], d) # ======================== # 経路の作成(貪欲法) # ======================== def dijkstra(i, j): """ ダイクストラを行い、経由点iから経由点jへの最短経路を復元する関数 """ dijkstra_dist = [INF for _ in range(len(points))] # 1つ前にいた頂点を保存する配列(経路復元用) prev_points = [-1 for _ in range(len(points))] # (距離, 頂点)のペアをpush queue = [(0, i)] dijkstra_dist[i] = 0 while queue: d, v = heapq.heappop(queue) if d > dijkstra_dist[v]: continue for next in range(len(points)): next_d = d + calc_energy(v, next) if next_d < dijkstra_dist[next]: # 1つ前の頂点を保存しておく prev_points[next] = v dijkstra_dist[next] = next_d heapq.heappush(queue, (next_d, next)) # ここから経路復元 # ゴールから1つずつ頂点を辿っていく # パンくずみたいな感じ v = j path = [] # スタートに戻るまでループ while v != i: path.append(v) v = prev_points[v] # pathには経路が逆順で入っているのでひっくり返す path.reverse() return path # 惑星1から出発し、一番近い惑星を貪欲に選び続ける(Nearest Neighbour法) v = 0 visited = [False] * n visited[0] = True route = [0] # 惑星1以外のN-1個の惑星を訪問していく for _ in range(n - 1): nearest_dist = INF nearest_v = -1 # 一番近い惑星を探す for next in range(n): if visited[next]: continue if distances[v][next] < nearest_dist: nearest_dist = distances[v][next] nearest_v = next # パスを復元 path = dijkstra(v, nearest_v) route.extend(path) # 次の頂点に移動 v = nearest_v visited[v] = True # 最後に惑星1に戻る必要がある path = dijkstra(v, 0) route.extend(path) # ======================== # 解の出力 # ======================== # 宇宙ステーションの座標を出力 for x, y in points[n:]: print(f"{x} {y}") # 経路の長さを出力 print(len(route)) # 経路を出力 for v in route: if v < n: print(f"1 {v + 1}") else: print(f"2 {v - n + 1}")