結果
| 問題 | No.3283 Labyrinth and Friends | 
| コンテスト | |
| ユーザー |  titia | 
| 提出日時 | 2025-10-01 04:09:42 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 1,086 ms / 2,000 ms | 
| コード長 | 1,501 bytes | 
| コンパイル時間 | 297 ms | 
| コンパイル使用メモリ | 82,232 KB | 
| 実行使用メモリ | 197,840 KB | 
| 最終ジャッジ日時 | 2025-10-01 04:09:52 | 
| 合計ジャッジ時間 | 10,097 ms | 
| ジャッジサーバーID (参考情報) | judge2 / judge5 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 2 | 
| other | AC * 45 | 
ソースコード
import sys
input = sys.stdin.readline
from operator import itemgetter
N,X=map(int,input().split())
P=list(map(int,input().split()))
PLUS=[list(map(int,input().split())) for i in range(N-1)]
E=[[] for i in range(N)]
for i in range(N-1):
    x=P[i]-1
    y=i+1
    E[x].append(y)
    E[y].append(x)
ROOT=0
QUE=[ROOT] 
Parent=[-1]*N
Parent[ROOT]=N # ROOTの親を定めておく.
Child=[[] for i in range(N)]
TOP_SORT=[] # トポロジカルソート
while QUE: # トポロジカルソートと同時に親を見つける
    x=QUE.pop()
    TOP_SORT.append(x)
    for to in E[x]:
        if Parent[to]==-1:
            Parent[to]=x
            Child[x].append(to)
            QUE.append(to)
def merge(A,B):
    C=[]
    for x,y in A:
        for z,w in B:
            C.append((min(X,x+z),y+w))
    C.sort(key=itemgetter(0))
    D=[(0,0)]
    for x,y in C:
        while len(D)>0 and D[-1][1]>=y:
            D.pop()
        if D==[] or D[-1][0]!=x:
            D.append((x,y))
    return D
    
        
    
DP=[[] for i in range(N)]
for x in TOP_SORT[::-1]:
    if x!=0:
        c,s=PLUS[x-1]
    else:
        c=0
        s=0
    
    if Child[x]==[]:
        DP[x]=[(0,0),(s,c)]
        continue
    NOW=[(0,0)]
    for cx in Child[x]:
        NOW=merge(NOW,DP[cx])
    NOW2=[(0,0)]
    for x0,y0 in NOW:
        NOW2.append((min(X,x0+s),y0+c))
        if x0+s>=X:
            break
    DP[x]=NOW2
ANS=1<<60
for x,y in DP[0]:
    if x>=X:
        ANS=min(ANS,y)
print(ANS)
            
            
            
        