[HAOI2015]树上染色(树形dp)
[HAOI2015]树上染色
题目描述
有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。
输入输出格式
输入格式:
第一行包含两个整数 N, K 。接下来 N-1 行每行三个正整数 fr, to, dis , 表示该树中存在一条长度为 dis 的边 (fr, to) 。输入保证所有点之间是联通的。
输出格式:
输出一个正整数,表示收益的最大值。
输入输出样例
输入样例#1: 复制
3 1
1 2 1
1 3 2
输出样例#1: 复制
3
说明
对于 100% 的数据, 0<=K<=N <=2000
题解
最开始我以为要处理出点与点之间的距离。
然后对于k的话实际上就是min(k,n-k)。
然后dp出最小价值的k个点对。
拿总路径和减去最小dp值。
但是发现不好维护。
于是抄看了题解
对于一个子树内我要选取的黑点。
我们这一次dp的不仅是增加的黑点的价值,还要处理出减少的白点的价值。
也就是说每选一个点,就要判断这条路径的贡献变化了多少。
对于每条路径的贡献。
为当前子树的黑节点×子树外的黑节点×边权+当前子树的白节点×子树外的白节点×边权就可以了。
这样就不用刻意去记录点对了。
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int N=2001;
struct node{
int to,nex;
ll v;
}e[N<<2];
int n,k,num,head[N],size[N];
ll f[N][N];
ll read(){
ll x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*w;
}
void add(int from,int to,int v){
num++;
e[num].to=to;
e[num].v=v;
e[num].nex=head[from];
head[from]=num;
}
void dfs1(int x,int fa){
size[x]=1;
for(int i=head[x];i;i=e[i].nex){
int v=e[i].to;
if(v==fa)continue;
dfs1(v,x);size[x]+=size[v];
}
}
void dfs2(int x,int fa){
f[x][0]=0;f[x][1]=0;
for(int i=head[x];i;i=e[i].nex){
int v=e[i].to;if(v!=fa){dfs2(v,x);
for(int j=min(size[x],k);j>=0;j--){
for(int l=0;l<=min(size[v],j);l++)
if(f[x][j-l]!=-1){
ll val=1ll*(l)*(k-l)*e[i].v+1ll*(size[v]-l)*(n-k+l-size[v])*e[i].v;
f[x][j]=max(f[x][j-l]+f[v][l]+val,f[x][j]);
}
}
}
}
}
int main(){
n=read();k=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
memset(f,-1,sizeof(f));
dfs1(1,1);dfs2(1,1);
printf("%lld\n",f[1][k]);
return 0;
}
[HAOI2015]树上染色(树形dp)的更多相关文章
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- 【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 ...
- bzoj4033 [HAOI2015]树上染色——树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033 树形DP,状态中加入 x 与父亲之间的边的贡献: 边权竟然是long long... ...
- BZOJ 4033 [HAOI2015]树上染色 ——树形DP
可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...
- 【HAOI2015】树上染色—树形dp
[HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...
- 【BZOJ4033】【HAOI2015】树上染色 树形DP
题目描述 给你一棵\(n\)个点的树,你要把其中\(k\)个点染成黑色,剩下\(n-k\)个点染成白色.要求黑点两两之间的距离加上白点两两之间距离的和最大.问你最大的和是多少. \(n\leq 200 ...
- 【HAOI2015】树上染色 - 树形 DP
题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...
- BZOJ_4033_[HAOI2015]树上染色_树形DP
BZOJ_4033_[HAOI2015]树上染色_树形DP Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并 将其他的 ...
随机推荐
- iOS开发——自动填充短信验证码
苹果在iOS 12,改进了一个很人性化的小细节.在做短信验证码功能的时候,自动获取短信中的验证码,然后点击填充即可.不用再向之前那样麻烦,自己看到弹出的短信信息后,死记硬背,再一个个敲上去,害怕背错了 ...
- C语言基本语法——预处理器和预处理指令
1.什么是预处理器 2.什么是预处理器指令 3.预处理器指令 4.宏指令 5.宏函数 6.宏函数的优缺点 7.条件编译指令 1.什么是预处理器 • 预处理器是一个程序,用来处理源程序中的预处理指令. ...
- pytorch 6 batch_train 批训练
import torch import torch.utils.data as Data torch.manual_seed(1) # reproducible # BATCH_SIZE = 5 BA ...
- ValidForm的使用
1.引入css 请查看下载文件中的style.css,把里面Validform必须部分拷贝到你的css中(文件中这个凝视 "/*==========下面部分是Validform必须的==== ...
- Yii2高速构建RESTful Web服务功能简单介绍
Yii2相比Yii1而言,一个重大的改进是内置了功能完备的RESTful支持. 其内置RESTful支持提供了例如以下功能: 使用ActiveRecord的通用接口来高速构建原型: 应答格式协商(缺省 ...
- adt-bundle-windows加入NDK支持
近期换了个硬盘,曾经都是用eclipse安装adt插件的,如今老了,图省事就下载了adt-bundle-windows,解压缩出来就直接用.但是这个adt-bundle没有集成NDK支持,于是手动安装 ...
- 实现 jstl标签foreach 功能
jsp 页面 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEn ...
- Java知识点解析
JAVA 1:简述Java的基本历史 java起源于SUN公司的一个GREEN的项目,其原先目的是为家用消费电子产品 发送一个信息的分布式代码系统,通过发送信息控制电视机.冰箱等. 2:简单写出Jav ...
- No connection could be made because the target machine actively refused it [::1]:808
No connection could be made because the target machine actively refused it [::1]:808 1.首先查看端口占用情况, 在 ...
- RAC连接时的2种方式Connect Time Failver和taf
1. Client-side Connect Time Failover 在客户端的tnsname中配置多个地址,当用户连接时会按照次序尝试各个地址,直到连接成功,连接好后,不再检测地址是否可用,如 ...