結果
問題 | No.5007 Steiner Space Travel |
ユーザー | titan23 |
提出日時 | 2022-07-30 16:01:30 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 946 ms / 1,000 ms |
コード長 | 3,747 bytes |
コンパイル時間 | 249 ms |
実行使用メモリ | 144,032 KB |
スコア | 2,379,200 |
最終ジャッジ日時 | 2022-07-30 16:02:01 |
合計ジャッジ時間 | 31,095 ms |
ジャッジサーバーID (参考情報) |
judge13 / judge15 |
純コード判定しない問題か言語 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 935 ms
140,024 KB |
testcase_01 | AC | 936 ms
141,952 KB |
testcase_02 | AC | 936 ms
141,880 KB |
testcase_03 | AC | 934 ms
139,436 KB |
testcase_04 | AC | 938 ms
135,808 KB |
testcase_05 | AC | 928 ms
140,952 KB |
testcase_06 | AC | 928 ms
139,836 KB |
testcase_07 | AC | 925 ms
139,992 KB |
testcase_08 | AC | 937 ms
142,496 KB |
testcase_09 | AC | 929 ms
139,476 KB |
testcase_10 | AC | 927 ms
141,560 KB |
testcase_11 | AC | 946 ms
141,460 KB |
testcase_12 | AC | 940 ms
142,240 KB |
testcase_13 | AC | 937 ms
139,952 KB |
testcase_14 | AC | 936 ms
139,676 KB |
testcase_15 | AC | 938 ms
139,720 KB |
testcase_16 | AC | 936 ms
144,008 KB |
testcase_17 | AC | 943 ms
139,524 KB |
testcase_18 | AC | 926 ms
141,776 KB |
testcase_19 | AC | 932 ms
139,920 KB |
testcase_20 | AC | 931 ms
142,600 KB |
testcase_21 | AC | 941 ms
140,788 KB |
testcase_22 | AC | 932 ms
144,032 KB |
testcase_23 | AC | 933 ms
140,968 KB |
testcase_24 | AC | 937 ms
143,404 KB |
testcase_25 | AC | 924 ms
141,520 KB |
testcase_26 | AC | 940 ms
120,604 KB |
testcase_27 | AC | 929 ms
139,900 KB |
testcase_28 | AC | 929 ms
141,144 KB |
testcase_29 | AC | 926 ms
139,876 KB |
ソースコード
import sys import time import random import math input = lambda: sys.stdin.readline().rstrip() from collections import defaultdict class UnionFind: def __init__(self, n: int): "Build a new UnionFind. / O(N)" self.__n = n self.__group_numbers = n self.__parents = [-1] * n def __find(self, x: int) -> int: a = x while self.__parents[a] >= 0: a = self.__parents[a] while self.__parents[x] >= 0: self.__parents[x] = a x = self.__parents[x] return a def unite(self, x: int, y: int) -> None: "Untie x and y. / O(α(N))" x, y = self.__find(x), self.__find(y) if x == y: return self.__group_numbers -= 1 if self.__parents[x] > self.__parents[y]: x, y = y, x self.__parents[x] += self.__parents[y] self.__parents[y] = x def size(self, x: int) -> int: "xが属する集合の要素数. / O(α(N))" return -self.__parents[self.__find(x)] def same(self, x: int, y: int) -> bool: "Return True if 'same' else False. / O(α(N))" return self.__find(x) == self.__find(y) def roots(self) -> list: "Return all roots. / O(N)" return [i for i,x in enumerate(self.__parents) if x < 0] def group_count(self) -> int: "Return the number of groups. / O(1)" return self.__group_numbers def all_group_members(self) -> list: "Return all_group_members. / O(Nα(N))" group_members = defaultdict(list) for member in range(self.__n): group_members[self.__find(member)].append(member) return group_members def relax(self) -> None: "/relax." for i in range(self.__n): self.__find(i) def __str__(self) -> str: ret = '<UnionFind> [\n' ret += '\n'.join(f' {k}: {v}' for k,v in self.all_group_members().items()) ret += '\n]\n' return ret # ----------------------- # n, m = map(int, input().split()) ab = [tuple(map(int, input().split())) for _ in range(n)] ab_set = set(ab) ALP = 5 LIMIT = 0.8 START = time.time() def MST(E): uf = UnionFind(n+m+1) E.sort(key=lambda x: -x[2]) used = [] cost = 0 for i,j,c in E: if uf.same(i, j): continue uf.unite(i, j) used.append((i, j)) cost += c return cost, used def make_stations(): stations = [] while len(stations) < m: i, j = random.randint(0, 1000), random.randint(0, 1000) if (i, j) in ab_set: continue stations.append((i, j)) E = [] for i in range(n+m): for j in range(n+m): if i == j: continue cost = 0 if i < n: if j < n: cost = ALP * ALP * ((ab[i][0] - ab[j][0])**2 + (ab[i][1] - ab[j][1])**2) else: cost = ALP * ((ab[i][0] - stations[j-n][0])**2 + (ab[i][1] - stations[j-n][1])**2) else: if j < n: cost = ALP * ((stations[i-n][0] - ab[j][0])**2 + (stations[i-n][1] - ab[j][1])**2) else: cost = ((stations[i-n][0] - stations[j-n][0])**2 + (stations[i-n][1] - stations[j-n][1])**2) E.append((i+1, j+1, cost)) score, mst = MST(E) return stations, score, mst from collections import deque def make_root(mst): G = [[] for _ in range(n+m+1)] for i,j in mst: G[i].append(j) G[j].append(i) ret = [] seen = set([1]) todo = deque([1]) while todo: v = todo.popleft() ret.append(v) for x in G[v]: if x in seen: continue todo.append(x) seen.add(x) return ret vestscore = float('inf') ans = [] while time.time() - START < LIMIT: stations, score, mst = make_stations() if score < vestscore: vestscore = score ans = [stations[:], mst[:]] root = make_root(ans[1]) for i in ans[0]: print(*i) print(len(root)+1) for i in root: if i <= n: print(1, i) else: print(2, i-n) print(1, 1)