analysis:
This is in fact given a binary tree, each non-leaf node choose a son, then for each leaf node, its contribution is saying is that there are several nodes as the left / right son is not selected related to the root chain, the minimum required contributions and.
Consider the tree $ DP $, but this contribution is a product, not convenient to directly split and merge do routine sub-tree from the bottom up.
Observation Data range: size of the tree. 4 $ \. 4 Times 10 ^ $ , $ 40 $ depth. Found for each leaf, then the information can be kept down on top of the enumeration; non-leaf nodes are enumerated top information, discuss two cases.
Provided $ f [u] [i] [j] $ represents: For the subtree $ U $, it is to the root strands has $ I $ a is not selected from the left child, $ J $ a selected right son, and the contribution of the sub-tree. Then $$ f [u] [i] [j] = min \ {f [ls] [i] [j] + f [rs] [i] [j + 1], f [ls] [i + 1] [j] + f [rs] [i] [j] \} $$
Problem solution and discussion area where it seems that this title card space, then we can $ DFS $ properties, set $ f [d] [i] [j] [0/1] $ denotes the $ d $ layer, left / right son answers. successfully passed.
Implementation (100):
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<map> #include<set> #define IL inline #define RG register #define _1 first #define _2 second using namespace std; typedef long long LL; const int N=2e4; const int M=40; int n,cit[N+3],vil[N+3]; struct Node{ bool iscity; LL a,b,c; int s[2]; }a[N*2+3]; int top; IL int pickcity(int i){ if(cit[i]==-1) return cit[i]=++top; return cit[i]; } LL f[M+3][M+3][M+3][2]; void dfs(int d,int t,int x,int rd,int ri){ if(a[x].iscity){ for(int i=0;i<2;i++) dfs(d+1,i,a[x].s[i],rd+(int)(i==0),ri+(int)(i==1)); for(int i=0;i<=rd;i++) for(int j=0;j<=ri;j++) f[d][i][j][t]=min(f[d+1][i][j][0]+f[d+1][i][j+1][1] ,f[d+1][i+1][j][0]+f[d+1][i][j][1]); } else { for(int i=0;i<=rd;i++) for(int j=0;j<=ri;j++) f[d][i][j][t]=a[x].c*(a[x].a+i)*(a[x].b+j); } } int main(){ scanf("%d",&n); top=-1; memset(cit,-1,sizeof cit); for(int i=1;i<n;i++){ int k=pickcity(i); a[k].iscity=true; a[k].s[0]=a[k].s[1]=-1; int s[2],t; scanf("%d%d",&s[0],&s[1]); for(int j=0;j<2;j++) if(s[j]>0){ t=pickcity(s[j]); a[t].iscity=true; a[k].s[j]=t; } else { t=++top; a[t].iscity=false; vil[-s[j]]=t; a[k].s[j]=t; } } for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&a[vil[i]].a,&a[vil[i]].b,&a[vil[i]].c); dfs(1,0,0,0,0); printf("%lld",f[1][0][0][0]); return 0; }
summary:
The data range selected convenient flexible algorithm.
When writing the title took some time to set up a node, a little Shousheng.