【BZOJ4033】【HAOI2015】树上染色 树形DP
题目描述
给你一棵\(n\)个点的树,你要把其中\(k\)个点染成黑色,剩下\(n-k\)个点染成白色。要求黑点两两之间的距离加上白点两两之间距离的和最大。问你最大的和是多少。
\(n\leq 2000\)
题解
我们考虑树形DP。
设\(f_{i,j}\)为以\(i\)为根的子树,染了\(j\)个黑点的最大收益。
若一条边的一端有\(s_1\)个点,选了\(j_1\)个黑点,另一端有\(s_2\)个点,选了\(j_2\)个黑点,那么这条边的贡献就是
\]
于是我们就可以从\(f_{x,i},f_{v,j}\)转移到\(f_{x,i+j}\)。
表面上看是\(O(n^3)\)的,因为要枚举选了几个黑点,实际上是\(O(n^2)\)的。
转移可以看成两边各选一个点,这个点\(x\)就是两边的点的lca。因为总共有\(O(n^2)\)个lca,所以就是\(O(n^2)\)的。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
ll upmin(ll &a,ll b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(ll &a,ll b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
struct graph
{
int v[5010];
int w[5010];
int t[5010];
int h[2010];
int n;
graph()
{
memset(h,0,sizeof h);
n=0;
}
void add(int x,int y,int z)
{
n++;
v[n]=y;
w[n]=z;
t[n]=h[x];
h[x]=n;
}
};
graph g;
ll f[2010][2010];
ll h[2010];
int s[2010];
int n,k;
void dfs(int x,int fa)
{
s[x]=1;
f[x][0]=f[x][1]=0;
int i,v,j,l;
for(i=g.h[x];i;i=g.t[i])
if(g.v[i]!=fa)
{
v=g.v[i];
dfs(v,x);
memset(h,0xc0,sizeof h);
for(j=0;j<=s[x]&&j<=k;j++)
for(l=0;l<=s[v]&&j+l<=k;l++)
if(n-k-s[v]+l>=0)
upmax(h[j+l],f[x][j]+f[v][l]+ll(g.w[i])*(ll(k-l)*l+ll(n-k-s[v]+l)*(s[v]-l)));
s[x]+=s[v];
for(j=0;j<=s[x]&&j<=k;j++)
f[x][j]=h[j];
}
}
int main()
{
scanf("%d%d",&n,&k);
int i,x,y,z;
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
g.add(x,y,z);
g.add(y,x,z);
}
memset(f,0xc0,sizeof f);
dfs(1,0);
printf("%lld\n",f[1][k]);
return 0;
}
【BZOJ4033】【HAOI2015】树上染色 树形DP的更多相关文章
- [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... ...
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 【BZOJ4033】[HAOI2015]树上染色 树形DP
[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- BZOJ 4033 [HAOI2015]树上染色 ——树形DP
可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...
- BZOJ4033 HAOI2015 树上染色 【树上背包】
BZOJ4033 HAOI2015 树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白 ...
- BZOJ4033: [HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3461 Solved: 1473[Submit][Stat ...
- [bzoj4033][HAOI2015]树上染色_树形dp
树上染色 bzoj-4033 HAOI-2015 题目大意:给定一棵n个点的树,让你在其中选出k个作为黑点,其余的是白点,收益为任意两个同色点之间距离的和.求最大收益. 注释:$1\le n\le 2 ...
随机推荐
- vue文档全局api笔记1
全局api方法 1.Vue.extend(options) 请注意,extend创建的是一个组件构造器,而不是一个具体的组件实例.所以他不能直接在new Vue中这样使用: new Vue({comp ...
- ssm知识点总结
项目名称:教育网—在线调查系统 项目总体流程图: 设计调查:调查-->包裹--->问题(增删改查) 1.调整包裹顺序 2.移动复制包裹 3.深度删除 创建调查流程分析: 主要生成surve ...
- 无法从带有索引像素格式的图像创建graphics对象
大家在用 .NET 做图片水印功能的时候, 很可能会遇到 “无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be ...
- python 实现快速排序
一.快排思想 快速排序可以理解为是对冒泡排序的一种改进,把一组数,按照初始选定的标杆(参照数), 分别从两端开始排序,左端'i'只要小于标杆(参照数)的数,右端'j'只要大于标杆(参照数)的数, i- ...
- linux中根据名称kill进程
shell函数如下: # kill processes by name kbn() { line=`ps -a | grep $1` arr=($line) for((i=0;i<${#arr[ ...
- latex 图片标题居中
1.有一个全局图片标题居中的方法: \usepackage[justification=centering]{caption} 2.如果排版时有的图标题想左对齐,有的想居中,前一个方法就不好了,这里可 ...
- PAT L2-013 红色警报
https://pintia.cn/problem-sets/994805046380707840/problems/994805063963230208 战争中保持各个城市间的连通性非常重要.本题要 ...
- Prometheus & SoundCloud
Prometheus 系统监控方案 一 - Vovolie - 博客园https://www.cnblogs.com/vovlie/p/Prometheus_CONCEPTS.html Prometh ...
- React-Native之轮播组件looped-carousel的介绍与使用
React-Native之轮播组件looped-carousel的介绍与使用 一,关于react-native轮播组件的介绍与对比 1,react-native-swiper在动态使用网页图片,多张图 ...
- laravel get和all区别
get ,all 都可以获取到模型 all 是直接获取所有,get 是在添加了许多约束之后获取模型,get前面如果不加约束条件的话,效果与all等同