• bzoj 4033


    树形DP,dp[i][j]表示i子树中,选了j个白点,i子树中所有边的贡献。

     1 /**************************************************************
     2     Problem: 4033
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:6568 ms
     7     Memory:32492 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio> 
    11 #define min(a,b) ((a)<(b)?(a):(b)) 
    12 #define max(a,b) ((a)>(b)?(a):(b)) 
    13 #define oo 0x3f3f3f3f3f3f3f3fLL 
    14 #define N 2010 
    15   
    16 typedef long long dnt; 
    17   
    18 int n, m; 
    19 int head[N], next[N+N], dest[N+N], wght[N+N], etot; 
    20 dnt siz[N]; 
    21 dnt dp[N][N], pp[N]; 
    22   
    23 void adde( int u, int v, int w ) { 
    24     etot++; 
    25     wght[etot] = w; 
    26     dest[etot] = v; 
    27     next[etot] = head[u]; 
    28     head[u] = etot; 
    29 } 
    30 void dfs( int u, int fa ) { 
    31     siz[u] = 1; 
    32     for( int t=head[u]; t; t=next[t] ) { 
    33         int v=dest[t]; 
    34         if( v==fa ) continue; 
    35         dfs( v, u ); 
    36         siz[u] += siz[v]; 
    37     } 
    38     int maxc = min( siz[u], m ); 
    39     for( int c=0; c<=maxc; c++ ) 
    40         pp[c] = -oo; 
    41     pp[0] = 0; 
    42     for( int t=head[u]; t; t=next[t] ) { 
    43         int v=dest[t], w=wght[t]; 
    44         if( v==fa ) continue; 
    45         for( int c=maxc; c>=0; c-- ) { 
    46             int msc = min( c, siz[v] ); 
    47             for( int sc=0; sc<=msc; sc++ ) { 
    48                 dnt tv = pp[c-sc]+dp[v][sc]+((dnt)sc*(m-sc)+(siz[v]-sc)*(n-m-siz[v]+sc))*w; 
    49                 pp[c] = max( pp[c], tv ); 
    50             } 
    51         } 
    52     } 
    53     dp[u][0] = pp[0]; 
    54     for( int c=1; c<=maxc; c++ ) 
    55         dp[u][c] = max( pp[c], pp[c-1] ); 
    56 } 
    57   
    58 int main() { 
    59     scanf( "%d%d", &n, &m ); 
    60     if( n-m<m ) m=n-m; 
    61     for( int i=1,u,v,w; i<n; i++ ) { 
    62         scanf( "%d%d%d", &u, &v, &w ); 
    63         adde( u, v, w ); 
    64         adde( v, u, w ); 
    65     } 
    66     dfs(1,1); 
    67     printf( "%lld
    ", dp[1][m] ); 
    68 } 
    69   
    View Code
  • 相关阅读:
    二叉树基本操作(二)
    二叉树基本操作(一)
    数组的方式实现--栈 数制转换
    数据的插入与删除
    链表 创建 插入 删除 查找 合并
    ACM3 求最值
    ACM2 斐波那契数列
    ACM_1 大数求和
    简单二维码生成及解码代码:
    ORM中去除反射,添加Expression
  • 原文地址:https://www.cnblogs.com/idy002/p/4469224.html
Copyright © 2020-2023  润新知