[BZOJ4033]:[HAOI2015]树上染色(树上DP)
题目传送门
题目描述
有一棵点数为N的树,树边有边权。给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益。
问收益最大值是多少。
输入格式
第一行两个整数N,K。
接下来N-1行每行三个正整数fr,to,dis,表示该树中存在一条长度为dis的边(fr,to)。
输入保证所有点之间是联通的。
N<=2000,0<=K<=N。
输出格式
输出一个正整数,表示收益的最大值。
样例
样例输入:
5 2
1 2 3
1 5 1
2 3 1
2 4 2
样例输出:
17
数据范围与提示
样例解释:将点1,2染黑就能获得最大收益。
N≤2000, 0≤K≤N。
题解
看提第一眼,树上DP。
定义dp[i][j]表示以i为根节点的子树上有j个黑点的最大收益。
那么,显然,这条边对答案的贡献只与它的子树内、外有几个黑点、白点有关,与它的子树的子树无关。
设点x的子树和为size[x],如果它的子树里有black个黑点,那么它的子树中就有size[x]-black个白点,它的子树外就有k-black个黑点,n-k-(size[x]-black)个白点,那么,这条边对答案的贡献就为{black×(size[x]-black)+(k-black)×[n-k-(size[x]-black)]}×边权。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec
{
int nxt;
int to;
int w;
}e[4000];
int head[2001],cnt;
int n,b;
long long dp[2001][2001],flag[2001];//记得开long long……
int size[2001];
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void dfs(int x)//树上DP
{
size[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
if(size[e[i].to])continue;
dfs(e[i].to);
memset(flag,0,sizeof(flag));
for(int j=0;j<=min(b,size[x]);j++)
for(int k=0;k<=min(b,size[e[i].to])&&j+k<=b;k++)
flag[j+k]=max(flag[j+k],dp[x][j]+dp[e[i].to][k]+(k*(b-k)+1LL*(size[e[i].to]-k)*(n-b-size[e[i].to]+k))*e[i].w);//转移
for(int j=0;j<=b;j++)dp[x][j]=flag[j];
size[x]+=size[e[i].to];
}
}
int main()
{
scanf("%d%d",&n,&b);
for(int i=1;i<n;i++)
{
int fr,to,dis;
scanf("%d%d%d",&fr,&to,&dis);
add(fr,to,dis);
add(to,fr,dis);
}
dfs(1);
cout<<dp[1][b]<<endl;
return 0;
}
rp++
[BZOJ4033]:[HAOI2015]树上染色(树上DP)的更多相关文章
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 【BZOJ4033】[HAOI2015]树上染色 树形DP
[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...
- [BZOJ4033][HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2437 Solved: 1034[Submit][Stat ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- [HAOI2015]树上染色(树上dp)
[HAOI2015]树上染色 这种要算点对之间路径的长度和的题,难以统计每个点的贡献.这个时候一般考虑算每一条边贡献了哪些点对. 知道这个套路以后,那么这题就很好做了. 状态:设\(dp[u][i]\ ...
- 【HAOI2015】树上染色—树形dp
[HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...
- 【BZOJ】4033: [HAOI2015]树上染色 树上背包
[题目]#2124. 「HAOI2015」树上染色 [题意]给定n个点的带边权树,要求将k个点染成黑色,使得 [ 黑点的两两距离和+白点的两两距离和 ] 最大.n<=2000. [算法]树上背包 ...
- 【BZOJ4033】【HAOI2015】树上染色 树形DP
题目描述 给你一棵\(n\)个点的树,你要把其中\(k\)个点染成黑色,剩下\(n-k\)个点染成白色.要求黑点两两之间的距离加上白点两两之间距离的和最大.问你最大的和是多少. \(n\leq 200 ...
- bzoj4033 [HAOI2015]树上染色——树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033 树形DP,状态中加入 x 与父亲之间的边的贡献: 边权竟然是long long... ...
- 【HAOI2015】树上染色 - 树形 DP
题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...
随机推荐
- NPOI_winfrom导出Excel表格(一)(合并单元格、规定范围加外边框、存储路径弹框选择)
1.导出 private void btn_print_Click(object sender, EventArgs e) { DataTable dtNew = new DataTable(); d ...
- maven简识
https://www.cnblogs.com/whgk/p/7112560.html 一:命令行管理maven项目: 创建maven[java]项目: D:\maven\demo>mvn ar ...
- 02 Go程序执行流程
一.把源码编译成二进制后执行 .go代码源文件 => go build => 可执行文件(.exe文件或者linux二进制文件) => 运行结果 二.对源码直接运行 .go源代码文件 ...
- mui APP 微信登录授权
一.在微信平台上申请appid.appsecret. 二.app --> manifest.json-->SDK配置(填写申请好的appid和appsecret) 三.在登录页,点击微信登 ...
- (๑•̀ㅂ•́)و✧QQ用户信息管理系统
这是第二篇文章,就直接切主题 这次剖析的也是自己的作业之一:QQ信息管理系统 一:(此处省略了建Proarams类,其实目的只是想强调把连接语句单独放一个类里更容易调用,命名规范如图) 二:(导入SQ ...
- Docker安装&java-Zookeeper进行操作
Docker安装Zookeeper下载Zookeeper镜像 docker pull zookeeper 启动容器并添加映射 docker run --privileged=: -d zookeepe ...
- ubuntu 共享WIFI并分享主机的代理服务
背景是这样的: 公司内的主机访问外网需要通过一个HTTP代理服务器,主机ubuntu共享wifi给手机使用的时候需要在手机上配置一个代理才能访问互联网. 我觉得这样比较麻烦,所以想在主机上直接把共享w ...
- MySQL导出数据到文件中
一.导出一张表数据 把test_time表中的数据导出成txt 文件 mysql> show global variables like '%secure%'; +--------------- ...
- 用Python输出一个Fibonacci数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列” 用文字来说, ...
- Java学习笔记【五、字符串】
String类 11种构造,不一一列举 常用方法 s.length() 返回字符串长度 s1.contact(s2) 连接s1.s2 String.format("aaa %f bbb %d ...