题目描述

有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。

输入输出格式

输入格式:

第一行包含两个整数 N, K 。接下来 N-1 行每行三个正整数 fr, to, dis , 表示该树中存在一条长度为 dis 的边 (fr, to) 。输入保证所有点之间是联通的。

输出格式:

输出一个正整数,表示收益的最大值。

思路

设 \(f_{i,j}\) 为以 \(i\) 为根的子树选 \(j\) 个点染成黑色的贡献。考虑一条边的贡献,它被一条路径经过就会产生贡献,经过这个点的路径的数量显然是左边黑色节点个数和右边黑色节点个数的积。就可以得出一个节点 \(u\) 被 \((j-m) \times j + (size_u-j) \times (n-m-size_u+j)\),其中 \(j\) 为已经选了的黑色节点个数,\(size\) 为子树大小。直接转移就行了

/************************************************
*Author : lrj124
*Created Time : 2019.03.18.20:14
*Mail : 1584634848@qq.com
*Problem : luogu3177
************************************************/
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2000 + 10;
struct Edge {
int to,val;
Edge(int v,int w) : to(v),val(w) {}
};
vector<Edge> edge[maxn];
long long f[maxn][maxn];
int n,K,size[maxn];
inline void dp(int now,int fa) {
size[now] = 1;
f[now][0] = f[now][1] = 0;
for (size_t i = 0;i < edge[now].size();i++)
if (edge[now][i].to ^ fa) {
dp(edge[now][i].to,now);
size[now] += size[edge[now][i].to];
}
for (size_t i = 0;i < edge[now].size();i++) if (edge[now][i].to ^ fa)
for (int j = min(K,size[now]);j >= 0;j--)
for (int k = 0;k <= min(j,size[edge[now][i].to]);k++)
if (f[now][j-k] >= 0) f[now][j] = max(f[now][j],f[now][j-k]+f[edge[now][i].to][k]+1ll*k*(K-k)*edge[now][i].val+1ll*(size[edge[now][i].to]-k)*(n-size[edge[now][i].to]-K+k)*edge[now][i].val);
}
int main() {
scanf("%d%d",&n,&K);
memset(f,128,sizeof(f));
for (int i = 1,u,v,w;i < n;i++) {
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back(Edge(v,w));
edge[v].push_back(Edge(u,w));
}
dp(1,0);
printf("%lld",f[1][K]);
return 0;
}

【HAOI2015】树上染色 - 树形 DP的更多相关文章

  1. 洛谷 P3177 [HAOI2015]树上染色 树形DP

    洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...

  2. bzoj 4033: [HAOI2015]树上染色 [树形DP]

    4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...

  3. 【BZOJ4033】[HAOI2015]树上染色 树形DP

    [BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...

  4. [BZOJ4033][HAOI2015]树上染色(树形DP)

    4033: [HAOI2015]树上染色 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2437  Solved: 1034[Submit][Stat ...

  5. bzoj4033 [HAOI2015]树上染色——树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033 树形DP,状态中加入 x 与父亲之间的边的贡献: 边权竟然是long long... ...

  6. BZOJ 4033 [HAOI2015]树上染色 ——树形DP

    可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...

  7. 【HAOI2015】树上染色—树形dp

    [HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...

  8. 【BZOJ4033】【HAOI2015】树上染色 树形DP

    题目描述 给你一棵\(n\)个点的树,你要把其中\(k\)个点染成黑色,剩下\(n-k\)个点染成白色.要求黑点两两之间的距离加上白点两两之间距离的和最大.问你最大的和是多少. \(n\leq 200 ...

  9. BZOJ_4033_[HAOI2015]树上染色_树形DP

    BZOJ_4033_[HAOI2015]树上染色_树形DP Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的 ...

随机推荐

  1. docker环境部署mysql

    参考文档 docker官方:https://hub.docker.com/_/mysql/?tab=description 部署步骤 1. 拉取镜像 这里我拉取了tag为5.7的镜像 docker p ...

  2. Google公布编程语言排名,第一竟然是他?

      没想到吧,Python 又拿第一了! 在 Google 公布的编程语言流行指数中,Python 依旧是全球范围内最受欢迎的技术语言!   01 为什么 Python 会这么火? 核心还是因为企业需 ...

  3. Ribbon负载均衡接口

    IRule--负载均衡规则 1.RounRobinRule:轮询负载均衡,通过累加取余获取服务,默认规则 2.RandomRule:随机负载均衡 3.WeightedResponseTimeRule: ...

  4. LeetCode 86 | 链表基础,一次遍历处理链表中所有符合条件的元素

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第53篇文章,我们一起来看LeetCode第86题,Partition List(链表归并). 本题的官方难度是M ...

  5. Python 简明教程 --- 26,Python 多进程编程

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 学编程最有效的方法是动手敲代码. 目录 1,什么是多进程 我们所写的Python 代码就是一个程序, ...

  6. java基础(五)--基本数据类型、占用字节、数值范围

    一.Java基本数据类型 基本数据类型有8种:byte.short.int.long.float.double.boolean.char 分为4类:整数型.浮点型.布尔型.字符型. 整数型:byte. ...

  7. ES Reindex用java来实现

    简单的: 核心代码 //发送请求 ReindexRequestBuilder builder=ReindexAction.INSTANCE.newRequestBuilder(client).sour ...

  8. python学习笔记1 -- 函数式编程之高阶函数 filter

    filter 函数用于过滤序列,与map 和reduce函数类似,作为高阶函数,他们也是同样的使用方法,filter(参数1, 参数2),参数1是一个函数,而参数2是一个序列. filter的作用是根 ...

  9. Python编程语言简介

    Python诞生于20世纪90年代初,由荷兰人吉多·范罗苏姆发明.那么,Python这一门编程语言是如何发明的呢?这之中又有怎么的故事呢?请看下面. 故事发生在1989年的圣诞节上,吉多先生为了打发无 ...

  10. Python os.statvfs() 方法

    概述 os.statvfs() 方法用于返回包含文件描述符fd的文件的文件系统的信息.高佣联盟 www.cgewang.com 语法 statvfs()方法语法格式如下: os.statvfs([pa ...