不说了吧,
n
o
i
p
noip
noip难度
d
p
dp
dp
f
[
i
]
[
j
]
[
k
]
f[i][j][k]
f[i][j][k]表示
i
i
i为根,两种路分别有
j
,
k
j,k
j,k个的最小值
大力
d
p
dp
dp就完了
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=20005;
const int M=45;
int n,f[N][M][M],a[N<<1],b[N<<1],c[N<<1],lc[N],rc[N];
inline int calc(int u,int A,int B){
if(u>n)return c[u]*(a[u]+A)*(b[u]+B);
return f[u][A][B];
}
void dfs(int u,int a,int b){
if(u>=n)return;
int v1,v2;
dfs(v1=lc[u],a+1,b);
dfs(v2=rc[u],a,b+1);
for(int i=0;i<=a;i++)
for(int j=0;j<=b;j++)
f[u][i][j]=min(calc(v1,i+1,j)+calc(v2,i,j),calc(v1,i,j)+calc(v2,i,j+1));
}
signed main(){
n=read();
for(int i=1;i<n;i++){
lc[i]=read(),rc[i]=read();
if(lc[i]<0)lc[i]=-lc[i]+n;
if(rc[i]<0)rc[i]=-rc[i]+n;
}
for(int i=1;i<=n;i++){
a[i+n]=read(),b[i+n]=read(),c[i+n]=read();
}
dfs(1,0,0);
cout<<f[1][0][0];
}