[ABC259F] Select Edges を Pythonで解く
考え方
木DPで解きます。ある頂点
親とのつながりを"持たない"場合の
辺の重みが正であれば、つなぐ方が重みの総和は大きくなりますので、通常は、DP2[
DP1[
実装メモ
from collections import deque
N = int(input())
d = list(map(int,input().split()))
E = [[]*N for _ in range(N)]
DP1 = [0] * N
DP2 = [0] * N
for _ in range(N-1):
u,v,w=map(int,input().split())
u-=1; v-=1
E[u].append([v,w])
E[v].append([u,w])
BFS(幅優先探索)を行い、親子関係を決定する。
深さレベルをlevelに記録する(レベルが大きい方が下位・子となる)。
level = [-1] * N
def BFS(s):
level[s] = 0
dq = deque([s])
arr = [s]
while dq:
v = dq.popleft()
for u,w in E[v]:
if level[u] >= 0:
continue
level[u] = level[v] + 1
dq.append(u)
arr.append(u)
return arr
arr = BFS(0)
arr.reverse()
子の場合にはさらに、DP2[
dif にはDP2[
def CntDP(v):
dif = []
for u,w in E[v]:
if level[u] < level[v] and d[v] > 0:
DP2[v] += w
else:
if DP2[u]-DP1[u] > 0:
dif.append(DP2[u]-DP1[u])
DP1[v] += DP1[u]
DP2[v] += DP1[u]
dif.sort(reverse=True)
if len(dif) > 0:
DP1[v] += sum(dif[:d[v]])
if d[v] > 0:
DP2[v] += sum(dif[:max(d[v]-1,0)])
for v in arr:
CntDP(v)
ans = DP1[0]
print(ans)
少しまどろっこしい実装になってしまいましたが、pythonでのAC(Accepted)コードの中では、実行時間も短めでメモリ量も少ない方だったので、良しとしました。
Discussion