博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】4033: [HAOI2015]树上染色 树上背包
阅读量:6269 次
发布时间:2019-06-22

本文共 1127 字,大约阅读时间需要 3 分钟。

【题目】

【题意】给定n个点的带边权树,要求将k个点染成黑色,使得 [ 黑点的两两距离和+白点的两两距离和 ] 最大。n<=2000。

【算法】树上背包

【题解】设f[i][j]表示子树i中有j个黑点对答案的贡献(包括点 i 到父亲的边 p ),由于边p的贡献只和 j 有关,所以最后再统计。

所以做树上背包即可,注意这题特殊在f[x][0]≠0,所以初始f[x][k]+=f[y][0],然后不要把0作为物品。

最后统计边p的贡献:w[p] *(子树内黑点*子树外黑点+子树内白点*子树外白点)。

常数问题:要尽可能避免枚举无用状态,不然常数太大了,优化见代码。

#include
#include
#include
#define ll long longusing namespace std;const int maxn=2010,inf=0x3f3f3f3f;struct edge{
int v,w,from;}e[maxn*2];int first[maxn],tot,n,K,sz[maxn];ll f[maxn][maxn];void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}ll max(ll a,ll b){
return a
=0;k--){ f[x][k]+=f[e[i].v][0];// for(int j=min(k,sz[e[i].v]);j>=1;j--)if(f[x][k-j]>-inf){
// f[x][k]=max(f[x][k],f[x][k-j]+f[e[i].v][j]); }else break; } } for(int i=0;i<=K;i++)if(f[x][i]>-inf)f[x][i]+=1ll*w*(1ll*i*(K-i)+1ll*(sz[x]-i)*(n-K-sz[x]+i));}int main(){ scanf("%d%d",&n,&K); for(int i=1;i
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/8553588.html

你可能感兴趣的文章
android中用ExpandableListView实现三级扩展列表
查看>>
%Error opening tftp://255.255.255.255/cisconet.cfg
查看>>
java读取excel、txt 文件内容,传到、显示到另一个页面的文本框里面。
查看>>
《从零开始学Swift》学习笔记(Day 51)——扩展构造函数
查看>>
python多线程队列安全
查看>>
[汇编语言学习笔记][第四章第一个程序的编写]
查看>>
android 打开各种文件(setDataAndType)转:
查看>>
补交:最最原始的第一次作业(当时没有选上课,所以不知道)
查看>>
Vue实例初始化的选项配置对象详解
查看>>
PLM产品技术的发展趋势 来源:e-works 作者:清软英泰 党伟升 罗先海 耿坤瑛
查看>>
vue part3.3 小案例ajax (axios) 及页面异步显示
查看>>
软件测试(二)之 Failure, Error & Fault
查看>>
浅谈MVC3自定义分页
查看>>
.net中ashx文件有什么用?功能有那些,一般用在什么情况下?
查看>>
select、poll、epoll之间的区别总结[整理]【转】
查看>>
CSS基础知识(上)
查看>>
PHP中常见的面试题2(附答案)
查看>>
角色权限分配
查看>>
明小子动力上传拿webshell.zip
查看>>
ES6 Module export与import复合使用
查看>>