結果
| 問題 | No.317 辺の追加 |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2016-02-29 19:28:13 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 518 ms / 2,000 ms |
| コード長 | 2,323 bytes |
| コンパイル時間 | 214 ms |
| コンパイル使用メモリ | 82,388 KB |
| 実行使用メモリ | 82,936 KB |
| 最終ジャッジ日時 | 2024-09-24 12:53:10 |
| 合計ジャッジ時間 | 11,881 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 38 |
ソースコード
class DisjointSet(object):
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
self.num = n # number of disjoint sets
def union(self, x, y):
self._link(self.find_set(x), self.find_set(y))
def _link(self, x, y):
if x == y:
return
self.num -= 1
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)
for w in dp[1:]:
print(w - 1)
def solve_min_coins(vs, ms, N):
'''
len(vs) 種類のコインがある。
コインの額面は vs[i], コインの枚数は ms[i]
sum(v * m for v, m in zip(vs, ms)) == N <= 10**5
が成り立つ。
1 から N 円までの各金額をコインであらわすとき、各金額における最小コイン枚数はいくつか?
'''
dp = [0] * (N + 1)
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):
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 update_dp_core(v, w, dp, cum):
for i in range(cum, 0, -1):
if dp[i]:
dpiv = dp[i + v]
if dp[i] + w < dpiv or dpiv == 0:
dp[i + v] = dp[i] + w
if dp[v] > w or dp[v] == 0:
dp[v] = w
N, ds = read_data()
solve2(N, ds)