题目就去洛谷看把
这一道题是一道很明显的树形dp,其实也不算很难
我们在dfs中定义root , x , y
root 表示当前的点 , x表示没翻新的公路的条数,y表示没翻新的铁路的条数
并且定义一个 dp[][][]记录三个量
记住:
千万不能memset,
千万不能memset,
千万不能memset,
否则你会死的难看
于是所以的dp就被赋值为0,只要判断值不为0就能直接用了
代码
#include <iostream>
#include <cstring>
using namespace std ;
typedef long long LL ;
const int N = 2e4 + 10 ;
struct tree {
int lc , rc ;
}tr[N] ; int n ;
struct village {
LL x , y , z ;
}vil[N] ;
LL dp[N][45][45] ;
LL flag ;
LL dfs ( int root , int x , int y ) {
if ( root >= n ) return vil[root-n+1].z * ( vil[root-n+1].x + x ) * ( vil[root-n+1].y + y ) ;
if ( dp[root][x][y] != 0 ) return dp[root][x][y] ;
dp[root][x][y] =
min ( dfs( tr[root].lc , x+1 , y ) + dfs( tr[root].rc , x , y ) ,
dfs( tr[root].lc , x , y ) + dfs( tr[root].rc , x , y+1 ) ) ;
return dp[root][x][y] ;
}
int main() {
cin >> n ;
for ( int i = 1 ; i < n ; i ++ ) {
cin >> tr[i].lc >> tr[i].rc ;
if ( tr[i].lc < 0 ) tr[i].lc = -tr[i].lc + n - 1 ;
if ( tr[i].rc < 0 ) tr[i].rc = -tr[i].rc + n - 1 ;
}
for ( int i = 1 ; i <= n ; i ++ )
cin >> vil[i].x >> vil[i].y >> vil[i].z ;
cout << dfs( 1 , 0 , 0 ) << endl ;
return 0 ;
}