結果
問題 |
No.417 チューリップバブル
|
ユーザー |
![]() |
提出日時 | 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()