[HAOI2015]树上染色(树形背包)
有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。
Solution
比较经典的树形背包问题。
如果只对点进行分析,情况会变得十分麻烦,不放考虑每条变的贡献,每条边会产生两边黑点数的乘积加上两边白点数的乘积。
这样的话我们直接跑背包就可以了,标准的树形背包是n^3的,但是这道题每颗字数背包体积有上限,总复杂度可以做到n^2.
Code
#include<iostream> #include<cstdio> #include<cstring> #define N 2009 using namespace std; long long dp[N][N]; int size[N],m,n,a,b,c,tot,head[N]; struct dsd {int n,to,l; }an[N<<1]; inline void add(int u,int v,int l) {an[++tot].n=head[u];an[tot].to=v;head[u]=tot;an[tot].l=l; } void dfs(int u,int fa) {size[u]=1;for(int i=head[u];i;i=an[i].n)if(an[i].to!=fa){int v=an[i].to;dfs(v,u);size[u]+=size[v];for(int j=min(m,size[u]);j>=0;--j)// for(int k=0;k<=min(j,size[v]);++k)if(dp[v][k]!=-0x3f3f3f3f){long long num=(long long)(k*(m-k)+(n-size[v]-(m-k))*(size[v]-k))*an[i].l;dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]+num);}} } int main() {scanf("%d%d",&n,&m);for(int i=1;i<n;++i){scanf("%d%d%d",&a,&b,&c);add(a,b,c);add(b,a,c);}memset(dp,-0x3f,sizeof(dp));for(int i=1;i<=n;++i)dp[i][0]=dp[i][1]=0;// dfs(1,0);cout<<dp[1][m];return 0; }
这种写法太慢了,并没有做到严格n^2,bzoj会TLE,下面这种写法是稳过的。
Code
#include<iostream> #include<cstdio> #include<cstring> #define N 2009 using namespace std; typedef long long ll; ll dp[N][N],size[N],m,n,a,b,c,tot,head[N],g[N]; struct dsd {ll n,to,l; }an[N<<1]; inline void add(ll u,ll v,ll l) {an[++tot].n=head[u];an[tot].to=v;head[u]=tot;an[tot].l=l; } ll mi(ll x,ll y){return x<y?x:y;} ll ma(ll x,ll y){return x<y?y:x;} void dfs(ll u,ll fa){size[u]=1;for(ll i=head[u];i;i=an[i].n)if(an[i].to!=fa){ll v=an[i].to;dfs(v,u);ll x=mi(m,size[u]),y=mi(m,size[v]);for(int j=0;j<=m;++j)g[j]=0;for(ll j=x;j>=0;--j)for(int k=0;k<=y;++k)if(j+k<=m){ll gyx=((ll)k*(m-k)+(n-size[v]-(m-k))*(size[v]-k))*an[i].l;g[j+k]=ma(g[j+k],dp[u][j]+dp[v][k]+gyx);}for(int j=0;j<=m;++j)dp[u][j]=g[j];size[u]+=size[v];} } inline int rd(){int x=0;char c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return x; } int main() {n=rd();m=rd();for(int i=1;i<n;++i){a=rd();b=rd();c=rd();add(a,b,c);add(b,a,c);}memset(dp,-0x3f,sizeof(dp));for(int i=1;i<=n;++i)dp[i][0]=dp[i][1]=0;dfs(1,0);printf("%lld",dp[1][m]);return 0; }
转载于:https://www.cnblogs.com/ZH-comld/p/9737789.html
[HAOI2015]树上染色(树形背包)相关推荐
- [BZOJ4033][HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2437 Solved: 1034 [Submit][St ...
- bzoj4033: [HAOI2015]树上染色(树形dp)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3269 Solved: 1413 [Submit][St ...
- Luogu P3177 [HAOI2015] 树上染色(树上背包)
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P3177 [HAOI2015] 树上染色 有一棵点数为 NNN 的树,树边有边权.给你一 ...
- bzoj 4033: [HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 1786 Solved: 754 [Submit][Sta ...
- [BZOJ4033][HAOI2015]树上染色
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 2108 Solved: 901 [Submit][Sta ...
- [HAOI2015]树上染色(树形dp,树形背包)
链接:https://ac.nowcoder.com/acm/problem/19996 来源:牛客网 题目描述 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个 ...
- 洛谷 P3177 [HAOI2015]树上染色
题目链接 题目描述 有一棵点数为 \(N\) 的树,树边有边权.给你一个在 \(0~ N\) 之内的正整数 \(K\) ,你要在这棵树中选择 \(K\)个点,将其染成黑色,并将其他 的\(N-K\)个 ...
- BZOJ 4033: [HAOI2015]树上染色
题解:看着题目感到恐惧,什么一个点选黑选白要是1e5我肯定会往淀粉质想了,就很害怕,我又不会..然后一看数据范围2000,于是突然开心,想写题.N-N^2应该美滋滋?dp[x][k]表示x的子树中选择 ...
- bzoj4033 [HAOI2015]树上染色
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033 重要的思路:与其考虑每一个点对的贡献,不如考虑每条边的贡献(==被经过了几次)! 树形 ...
最新文章
- 京东超大规模联邦学习探索实践
- java se翻译_(翻译)Java SE 8 Lambda 标准库概览(下)
- oracle 服务管理,管理 Oracle 内容服务类别
- java pc计数器_java虚拟机-程序计数器PC Register
- 使用Java中的equals()和compareTo()方法比较字符串
- 深入了解Zookeeper核心原理
- react-native ios打包和Android打包
- linux 查询 lib信息,linux系统信息常用查询命令
- windows下db2的一些使用心得(不含安装)
- mybatis 业务逻辑
- 《编写有效用例》阅读笔记05
- 使用apache benchmark(ab) 测试报错: apr_socket_recv: Connection timed out (110)
- 让基础设施代码化更加容易,pulumi 都做了些什么?
- 微软去年安全业务收入150亿美元、新勒索软件以威联通设备为目标|1月27日全球网络安全热点
- CI框架实现某字段自加数值
- 本周上榜的这9本原创技术书很赞,《数学之美》作者吴军博士新书霸榜
- 微信小程序开发工具整理代码快捷键
- python识别二维码条形码?用pyzbar一招搞掂(含代码)!
- 云原生编程语言ballerina:hello-world
- CTF-RSA分解模数N