• BZOJ4033 [HAOI2015]T1


    令$f[p][i]$表示以$p$为根的子树内,选了$i$个黑点,剩下的都是白点的这个子树内贡献的答案

    如果$p$的子树都算出来了,只要计算$p$与$fa[p]$之间的边对答案的贡献就好了,贡献是$dis * (i * (sz - i) + (k - i) * (n - k - (sz - i)))$

    于是树形动规一下就好了

     1 /**************************************************************
     2     Problem: 4033
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:308 ms
     7     Memory:32300 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cstring>
    12 #include <algorithm>
    13  
    14 using namespace std;
    15 typedef long long ll;
    16  
    17 const int N = 2e3 + 5;
    18  
    19 struct edge {
    20     int next, to, v;
    21     edge(int _n = 0, int _t = 0, int _v = 0) : next(_n), to(_t), v(_v) {}
    22 } e[N << 1];
    23  
    24 int n, k;
    25 int first[N], tot;
    26 int sz[N];
    27 ll f[N][N], tmp[N];
    28  
    29 inline void Add_Edges(int x, int y, int z) {
    30     e[++tot] = edge(first[x], y, z), first[x] = tot;
    31     e[++tot] = edge(first[y], x, z), first[y] = tot;
    32 }
    33  
    34 inline ll calc(int x, int y) {
    35     return 1ll * y * (x - y);
    36 }
    37  
    38 #define y e[x].to
    39 inline void dfs(int p, int fa, int w) {
    40     int x, i, j;
    41     sz[p] = 1;
    42     for (x = first[p]; x; x = e[x].next)
    43         if (y != fa) {
    44             dfs(y, p, e[x].v);
    45             memcpy(tmp, f[p], sizeof(tmp));
    46             for (i = min(sz[p], k); ~i; --i)
    47                 for (j = min(sz[y], k - i); ~j; --j)
    48                     tmp[i + j] = max(tmp[i + j], f[p][i] + f[y][j]);
    49             memcpy(f[p], tmp, sizeof(tmp));
    50             sz[p] += sz[y];
    51         }
    52     for (i = min(sz[p], k); ~i; --i)
    53         f[p][i] += (calc(k, i) + calc(n - k, sz[p] - i)) * w;
    54 }
    55 #undef y
    56  
    57 int main() {
    58     int i, x, y, z;
    59     scanf("%d%d", &n, &k);
    60     for (i = 1; i < n; ++i) {
    61         scanf("%d%d%d", &x, &y, &z);
    62         Add_Edges(x, y, z);
    63     }
    64     dfs(1, 0, 0);
    65     printf("%lld
    ", f[1][k]);
    66     return 0;
    67 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    javascript之Number
    javascript之window对象
    javascript全局对象
    javascript之尺寸,位置,溢出
    javascript之DOM操作
    javascript之全局函数
    javascript之Error
    javascript之url转义escape()、encodeURI()和decodeURI()
    javascript之Boolean
    javascript之Arguments
  • 原文地址:https://www.cnblogs.com/rausen/p/4477718.html
Copyright © 2020-2023  润新知