結果
| 問題 |
No.417 チューリップバブル
|
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-20 20:52:30 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 157 ms / 2,000 ms |
| コード長 | 4,738 bytes |
| コンパイル時間 | 146 ms |
| コンパイル使用メモリ | 82,540 KB |
| 実行使用メモリ | 78,188 KB |
| 最終ジャッジ日時 | 2025-03-20 20:52:40 |
| 合計ジャッジ時間 | 4,913 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 40 |
ソースコード
import sys
from collections import defaultdict
def main():
sys.setrecursionlimit(1 << 25)
N, M = map(int, sys.stdin.readline().split())
U = [int(sys.stdin.readline()) for _ in range(N)]
edges = [[] for _ in range(N)]
for _ in range(N-1):
A, B, C = map(int, sys.stdin.readline().split())
edges[A].append((B, C))
edges[B].append((A, C))
parent = [None] * N
children = [[] for _ in range(N)]
stack = [0]
visited = [False] * N
visited[0] = True
while stack:
u = stack.pop()
for v, c in edges[u]:
if not visited[v]:
visited[v] = True
parent[v] = (u, c)
children[u].append((v, c))
stack.append(v)
post_order = []
visited = [False] * N
stack = [(0, False)]
while stack:
u, done = stack.pop()
if done:
post_order.append(u)
continue
visited[u] = True
stack.append((u, True))
for v, c in reversed(children[u]):
if not visited[v]:
stack.append((v, False))
dp_case_b = [defaultdict(int) for _ in range(N)]
for u in post_order:
if u == 0:
current_dp = defaultdict(int)
current_dp[0] = 0
for v, c_edge in children[u]:
child_dp = dp_case_b[v]
new_current = defaultdict(int)
for cost in current_dp:
current_u = current_dp[cost]
for c_cost in child_dp:
c_u = child_dp[c_cost]
total_cost = cost + c_cost
if total_cost > M:
continue
if new_current[total_cost] < current_u + c_u:
new_current[total_cost] = current_u + c_u
for cost in new_current:
if new_current[cost] > current_dp.get(cost, 0):
current_dp[cost] = new_current[cost]
for cost in child_dp:
c_u = child_dp[cost]
if cost <= M and c_u > current_dp.get(cost, 0):
current_dp[cost] = c_u
add_u = U[u]
new_current = defaultdict(int)
for cost in current_dp:
new_u = current_dp[cost] + add_u
if new_u > new_current.get(cost, 0):
new_current[cost] = new_u
for cost in new_current:
if new_current[cost] > current_dp.get(cost, 0):
current_dp[cost] = new_current[cost]
dp_case_b[u] = current_dp
else:
p, c_edge = parent[u]
edge_cost = c_edge * 2
current_dp = defaultdict(int)
current_dp[edge_cost] = 0
for v, c_child in children[u]:
child_dp = dp_case_b[v]
new_current = defaultdict(int)
for cost in current_dp:
current_u = current_dp[cost]
for c_cost in child_dp:
c_u = child_dp[c_cost]
total_cost = cost + c_cost
if total_cost > M:
continue
if new_current[total_cost] < current_u + c_u:
new_current[total_cost] = current_u + c_u
for cost in new_current:
if new_current[cost] > current_dp.get(cost, 0):
current_dp[cost] = new_current[cost]
for cost in child_dp:
c_u = child_dp[cost]
total_cost = edge_cost + cost
if total_cost > M:
continue
if (current_dp.get(total_cost, 0)) < current_dp.get(edge_cost, 0) + c_u:
current_dp[total_cost] = current_dp[edge_cost] + c_u
add_u = U[u]
new_current = defaultdict(int)
for cost in current_dp:
new_u = current_dp[cost] + add_u
new_cost = cost
if new_cost > M:
continue
if new_u > new_current.get(new_cost, 0):
new_current[new_cost] = new_u
for cost in new_current:
if new_current[cost] > current_dp.get(cost, 0):
current_dp[cost] = new_current[cost]
dp_case_b[u] = current_dp
max_u = 0
root_dp = dp_case_b[0]
for cost in root_dp:
if cost <= M and root_dp[cost] > max_u:
max_u = root_dp[cost]
print(max_u)
if __name__ == "__main__":
main()
lam6er