結果
| 問題 | No.317 辺の追加 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-02-29 23:05:32 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 360 ms / 2,000 ms |
| コード長 | 2,371 bytes |
| 記録 | |
| コンパイル時間 | 406 ms |
| コンパイル使用メモリ | 82,916 KB |
| 実行使用メモリ | 82,916 KB |
| 最終ジャッジ日時 | 2024-09-24 13:01:58 |
| 合計ジャッジ時間 | 11,164 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 38 |
ソースコード
class DisjointSet(object):
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
def union(self, x, y):
self._link(self.find_set(x), self.find_set(y))
def _link(self, x, y):
if x == y:
return
if self.rank[x] > self.rank[y]:
self.parent[y] = x
else:
self.parent[x] = y
if self.rank[x] == self.rank[y]:
self.rank[y] += 1
def find_set(self, x):
xp = self.parent[x]
if xp != x:
self.parent[x] = self.find_set(xp)
return self.parent[x]
def read_data():
N, M = map(int, input().split())
ds = DisjointSet(N)
for m in range(M):
u, v = map(int, input().split())
u -= 1
v -= 1
if u == v:
continue
ds.union(u, v)
return N, ds
def solve2(N, ds):
counts = [0] * N
for i in range(N):
counts[ds.find_set(i)] += 1
freqs = [0] * (N + 1)
for c in counts:
freqs[c] += 1
vs = []
ms = []
for i, f in enumerate(freqs):
if f and i:
vs.append(i)
ms.append(f)
dp = solve_min_coins(vs, ms, N)
n1 = N + 1
for w in dp[1:]:
print((w % n1) - 1)
def solve_min_coins(vs, ms, N):
dp = [N + 1] * (N + 1)
dp[0] = 0
cum = 0
for v, m in zip(vs, ms):
cum = update_dp(v, m, dp, cum)
return dp
def update_dp(v, m, dp, cum):
if v == 1:
for i in range(m + 1):
dp[i] = i
return cum + v * m
if v == 2:
if dp[1] == 1:
fill_dp_2a(v, m, dp, cum)
else:
fill_dp_2b(v, m, dp, cum)
return cum + v * m
pow2 = 1
while pow2 < m:
update_dp_core(v * pow2, pow2, dp, cum)
cum += v * pow2
m -= pow2
pow2 <<= 1
update_dp_core(v * m, m, dp, cum)
return cum + v * m
def fill_dp_2a(v, m, dp, cum):
for i in range(m + 1):
dp[i * 2] = i
dp[i * 2 + 1] = i + 1
for i in range(m * 2 + 2, cum + m * 2 + 1):
dp[i] = i - m
def fill_dp_2b(v, m, dp, cum):
for i in range(m + 1):
dp[i * 2] = i
def update_dp_core(v, w, dp, cum):
for i in range(cum, -1, -1):
iv = i + v
if dp[i] + w < dp[iv]:
dp[iv] = dp[i] + w
N, ds = read_data()
solve2(N, ds)