zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    当我有一台服务器时我做了什么
    git 安装及基本配置
    关于大厂面试中问到的二十几个 HTTP 面试题
    日问周刊 | 全栈面试汇总 | 第七期
    dockerfile 最佳实践及示例
    面试官:如果 http 响应头中 ETag 值改变了,是否意味着文件内容一定已经更改
    Nginx 反向代理时获取用户的真实 IP
    Go 语言实现 HTTP 层面的反向代理
    Go 语言中的 Http 路由基础
    Json Schema
  • 原文地址:https://www.cnblogs.com/rausen/p/4477718.html
Copyright © 2011-2022 走看看