点此看题面

大致题意: 给你一棵点数为N的带权树,要你在这棵树中选择K个点染成黑色,并将其他的N-K个点染成白色。要求你求出黑点两两之间的距离加上白点两两之间距离的和的最大值。

树形\(DP\)

这道题应该是一道比较显然的树形\(DP\),我们可以用f[x][i]来表示当前节点为x时有i个黑色节点时能取得的最大值。则转移方程应为(伪代码)

f[x][i]=max(f[x][i],f[x][i-j]+f[x的一个子节点][j]+j*(m-j)*x与这个子节点之间边的边权+1LL*(Size[x的子节点]-j)*(n-m+j-Size[x的子节点])*边的边权);

既然推出了转移方程,那么这题就好做了,只要先用dfs预处理,再DP就可以了。

代码

#include<bits/stdc++.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define LL long long
#define N 2000
using namespace std;
int n,m,ee=0,lnk[N+5],fa[N+5],vis[N+5],Size[N+5];
LL f[N+5][N+5];
struct edge
{
int to,nxt,val;
}e[2*N+5];
inline char tc()
{
static char ff[100000],*A=ff,*B=ff;
return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0;int f=1;char ch;
while(!isdigit(ch=tc())) if(ch=='-') f=-1;
while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
x*=f;
}
inline void write(LL x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline void add(int x,int y,int z)
{
e[++ee]=(edge){y,lnk[x],z},lnk[x]=ee;
}
inline int dfs(int x)//dfs预处理出每个节点的父亲以及子树大小
{
register int i;
for(Size[x]=1,i=lnk[x];i;i=e[i].nxt)
if(e[i].to^fa[x]) fa[e[i].to]=x,Size[x]+=dfs(e[i].to);
return Size[x];
}
inline void dp(int x)//DP的核心内容
{
vis[x]=1;//标记已访问
register int y,i,j;
for(y=lnk[x];y;y=e[y].nxt)
{
if(vis[e[y].to]) continue;
dp(e[y].to);
for(i=min(Size[x],m);i>=0;--i)
for(j=0;j<=min(Size[e[y].to],i);++j)
f[x][i]=max(f[x][i],f[x][i-j]+f[e[y].to][j]+1LL*j*(m-j)*e[y].val+1LL*(Size[e[y].to]-j)*(n-m+j-Size[e[y].to])*e[y].val);//转移方程
}
}
int main()
{
freopen("a.in","r",stdin);
register int i;int x,y,z;
for(read(n),read(m),i=1;i<n;++i)
read(x),read(y),read(z),add(x,y,z),add(y,x,z);
dfs(1);
2*m>n?m=n-m:0;//一个非常重要的优化,没有可能会TLE,原理在于在树上将m个节点染成黑色与将n-m个节点染成黑色其实是等价的
memset(f,167,sizeof(f));
for(i=1;i<=n;++i)
f[i][0]=f[i][1]=0;
return dp(1),write(f[1][m]),0;
}

【BZOJ4033】[HAOI2015] 树上染色(树形DP)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. BZOJ4033 HAOI2015 树上染色 【树上背包】

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

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

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

  9. [bzoj4033][HAOI2015]树上染色_树形dp

    树上染色 bzoj-4033 HAOI-2015 题目大意:给定一棵n个点的树,让你在其中选出k个作为黑点,其余的是白点,收益为任意两个同色点之间距离的和.求最大收益. 注释:$1\le n\le 2 ...

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

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

随机推荐

  1. PAT 1071【STL string应用】

    1.单case很多清空没必要的 2.string+ char 最好用pushback 3.string +string就直接+ #include <bits/stdc++.h> using ...

  2. ASP.NET控件之CompareValidator控件

    作用:对Textbox或者其他输入框进行比较验证: 属性:ControlToValidate:要验证的控件: ErrorMessage:错误提示信息: ControlToCompare:与此相比的控件 ...

  3. cf779D(记忆化dp)

    题目链接: http://codeforces.com/problemset/problem/799/D 题意: 给出两个矩阵边长 a, b, 和 w, h, 以及一个 c 数组, 可选择 c 数组中 ...

  4. ByteBuffer flip描述

    # 关于flip ByteBuffer 的filp函数, 将缓冲区的终止位置limit设置为当前位置, 缓冲区的游标position(当前位置)重设为0. 比如 我们有初始化一个ByteBuffer ...

  5. flask数据操纵

    Flask ORM 在Django框架中内部已经提供ORM这样的框架,来实现对象关系映射,方便我们操作数据库.如果想在Flask中也达到这样效果,需要安装一个第三方来支持. SQLAlchemy是一个 ...

  6. sql 存储过程-proc

    创建 create proc 存储过程名 (参数列表) as sql 语句 go 执行 exec 存储过程名 参数1,参数2 删除 drop procedure  存储过程名 注: 存储过程名最好以_ ...

  7. JMeter - 如何测试REST API / 微服务

    概述: 有许多方法和工具可用于测试REST API.当我需要测试REST API时,在查看了各种工具和选项之后,由于以下原因,我选择了JMeter. JMeter是免费和开源的. JMeter可以从C ...

  8. Java文件与io——装饰者模式

    意图: 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比于生成子类更为灵活.该模式以对客户端透明的方式扩展对象的功能. 适用环境 在不影响其他对象的情况下,以动态.透明的 ...

  9. android 开发-Toast控件的实现

    Toast吐司: Toast内容简单,不做过多介绍,Toast支持自带简单吐司,自定义吐司.内容简单可见代码,详见API.A toast provides simple feedback about ...

  10. Promise 用es5的基础实现

    只实现 then 和 catch function promise(fn) { var state = 'pending'; // 声明函数 var nowResolve = function (ar ...