洛谷 P3177 树上染色 解题报告
P3177 [HAOI2015]树上染色
题目描述
有一棵点数为\(N\)的树,树边有边权。给你一个在\(0\) ~ \(N\)之内的正整数\(K\),你要在这棵树中选择\(K\)个点,将其染成黑色,并将其他的\(N-K\)个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。
输入输出格式
输入格式:
第一行包含两个整数 \(N, K\) 。接下来 \(N-1\) 行每行三个正整数 \(fr, to, dis\) , 表示该树中存在一条长度为\(dis\)的边\((fr,to)\) 。输入保证所有点之间是联通的。
输出格式:
输出一个正整数,表示收益的最大值。
说明
对于\(100%\)的数据,\(0<=K<=N <=2000\)
这里阐述一下我的思考方式。
首先,真的一下子想到贪心去了。前几天做了消防,觉得在树的直径上会有一些奇妙优美的性质,遂开始想办法证明。
然后考试完了还在证贪心\(emmmm\)。
解法很容易懂,但是很难想(我太蒻了)
正解是树形\(DP\)
令\(dp[i][j]\)为以\(i\)为根节点的子树中 在染了\(j\)个黑点时 所有的边再加上\(i\)头上的那个边 对整颗树 的答案贡献
有灵性就有灵性在这个整颗树上
在已经处理好子树\(v\)时,我们加入边\(E_k(u,v)\)(\(u\)为\(v\)的父亲)
则\(E_k\)的贡献即为边权\(w*\)子树\(u\)中白点个数子树\(u\)外面的数白点个数\(+w*\)子树\(u\)中黑点个数子树\(u\)外面的数黑点个数,这点不难想明白
当然,不做头顶上的边也是可以的,但很多树形\(dp\)管一下自己的脑门是比较方便的
转移时,我们对每棵子树做树上分组背包,最后在判断一下她自己头上的边
code
#include <cstdio>
#include <cstring>
#define ll long long
ll max(ll x,ll y) {return x>y?x:y;}
ll min(ll x,ll y) {return x<y?x:y;}
const int N=2001;
ll dp[N][N];
//根节点为i的子树j个点染黑所有边的最大答案
ll n,k;
struct Edge
{
ll to,next,w;
}edge[N*2];
ll head[N],cnt=0;
void add(ll u,ll v,ll w)
{
edge[++cnt].to=v;
edge[cnt].next=head[u];
edge[cnt].w=w;
head[u]=cnt;
}
int used[N];
ll dfs(ll u,ll c)
{
used[u]=1;
ll size=0;
memset(dp[u],-1,sizeof(dp[u]));
dp[u][0]=0;
for(ll i=head[u];i;i=edge[i].next)
{
ll v=edge[i].to,w=edge[i].w;
if(!used[v])
{
ll si=dfs(v,w);size+=si;
for(ll j=min(k,size);j>=0;j--)
{
ll r=min(j,min(si,k));
for(ll k0=0;k0<=r;k0++)
if(dp[u][j-k0]!=-1)
dp[u][j]=max(dp[u][j],dp[u][j-k0]+dp[v][k0]);
}
}
}
size++;
ll l=max(size+k-n,1);
for(ll i=min(k,size);i>=l;i--)
{
ll cc=c*(k-i)*i+c*(n-size-k+i)*(size-i);
dp[u][i]=max(dp[u][i],dp[u][i-1])+cc;
}
l=size+k-n;
dp[u][0]+=c*(n-size-k)*size;
return size;
}
int main()
{
scanf("%lld%lld",&n,&k);
ll u,v,w;
for(ll i=1;i<n;i++)
{
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
dfs(1,0);
printf("%lld\n",dp[1][k]);
return 0;
}
细节问题:
1.分组背包转移方程为:\(dp[u][j]=max(dp[u][j],dp[u][j-k0]+dp[v][k0])\)
我们一定要判断\(dp[u][j-k0]\)的合法性
2.开\(long long\)不要吝啬空间(除非卡的太死,反正也就两倍),能看尽量就开,只开一部分在计算时真的不注意就可能丢失了或者爆了
3.背包的上下界,最好加上,不然常数一大可能会\(t\)。有的不加甚至会出现一些问题。
2018.5.15
洛谷 P3177 树上染色 解题报告的更多相关文章
- 洛谷 P2664 树上游戏 解题报告
P2664 树上游戏 题目描述 \(\text{lrb}\)有一棵树,树的每个节点有个颜色.给一个长度为\(n\)的颜色序列,定义\(s(i,j)\) 为 \(i\) 到 \(j\) 的颜色数量.以及 ...
- 洛谷 P3177 树上染色
题面 题目要求将k个点染成黑色,求黑点两两距离及白点两两距离,使他们之和最大. 我们可以将距离转化为路径,然后再将路径路径拆分成边,就可以记录每条边被经过的次数,直接计算即可. 很简单对吧?那么问题来 ...
- 洛谷P3177 树上染色
题目 一道非常好的树形DP. 状态:\(dp[u][n]\)为u的子树选n个黑点所能得到的收益最大值. 则最终的结果就是\(dp[root][k],\)\(root\)可以为任何值,为了方便,使\(r ...
- 洛谷 P1783 海滩防御 解题报告
P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...
- 洛谷 P4597 序列sequence 解题报告
P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...
- 洛谷1087 FBI树 解题报告
洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...
- 洛谷 P4211 [LNOI2014]LCA 解题报告
[LNOI2014]LCA 题意 给一个\(n(\le 50000)\)节点的有根树,询问\(l,r,z\),求\(\sum_{l\le i\le r}dep[lca(i,z)]\) 一直想启发式合并 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
- 洛谷 P2245 星际导航 解题报告
P2245 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向 ...
随机推荐
- CSS中编写省略号代码片段
#component-content #dtMain .dt-ul > li .component-item .component-name{ display:inline-block; ...
- python标准库:collections和heapq模块
http://blog.csdn.net/pipisorry/article/details/46947833 python额外的数据类型.collections模块和heapq模块的主要内容. 集合 ...
- 神奇的layout_weight属性
1.概述 在线性布局有时候为了控制一下屏幕的适配,可以使用layout_weight这个属性来设置权重,要注意一点,这个属性只有在Linearlayout中才有效,这个属性往往会随着android:l ...
- FFMPEG列出DirectShow支持的设备
FFMPEG列出dshow支持的设备: ffmpeg -list_devices true -f dshow -idummy 举例: 采集摄像头和麦克风 ffmpeg -f dshow -i vide ...
- java的参数传递与内存分配问题
本文可作为北京尚学堂java课程的学习笔记. 看下面这段代码. class BirthDate { private int day; private int month; private int ye ...
- 算法精解:最小二乘法C实现
计量经济学研究的直接目的是确定总体回归函数Yi=B1+B2Xi+ui,然而能够得到的只是来自总体的若干样本的观测值,要用样本信息建立的样本回归函数尽可能"接近"地去估计总体回归函数 ...
- windows下c语言获取程序当前的执行目录,读文件的代码片
代码如下: #include "stdafx.h" #include "stdlib.h" #include <direct.h> #include ...
- iOS中判断照片和相机权限
1.照片权限判断 在iOS6之后,app中使用照片(即自带相册)需要用户权限验证,所以我们可以做一个权限判断给出友好的提示或者界面效果. 相册判断需要导入 <AssetsLibrary/Asse ...
- Android特效专辑(七)——飞机升空特效,一键清理缓存,灵活运用动画会有不一样的感受
Android特效专辑(七)--飞机升空特效,一键清理缓存,灵活运用属性动画 最近的几篇博文反响还不错,也会继续的写下去的,关于这些特效的专辑,大多数也是借鉴大神的,最近由于工作的关系,会深入的了解一 ...
- C++语言之静态变量的运用
#include <iostream> using namespace std ; class Banana { public: static int id ; Banana(void) ...