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

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

树DP 。 

考虑每条边对答案的贡献是边两边的黑点数乘积加白点数乘积乘以边长。所以我们只要知道一个点的某个子树中的黑点数就可以算它到子树这条边的贡献。

就可以树上跑背包。

注意一是不要随便只开单向边(会GG),二是DP初值设为-1,dp[x][0].dp[x][1]初始为0,这样不会考虑不存在的状态。

#include
#include
#include
#include
#include
#include
#include
typedef long long LL;using namespace std;const int maxn=2005;int n,k,x,y,z,fir[maxn],nxt[maxn*2],to[maxn*2],ecnt,sz[maxn];LL val[maxn*2],dp[maxn][maxn];void add(int u,int v,LL w) { nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w; nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;}void DFS(int x,int f) { sz[x]=1; for(int i=fir[x];i;i=nxt[i]) if(to[i]!=f){ DFS(to[i],x); sz[x]+=sz[to[i]]; }}void dfs(int x,int f) { memset(dp[x],-1,sizeof(dp[x])); dp[x][0]=dp[x][1]=0; for(int i=fir[x];i;i=nxt[i]) if(to[i]!=f){ dfs(to[i],x); int u=to[i],up=min(k,sz[x]); for(int v=up;v>=0;v--) { for(int j=0;j<=sz[u]&&j<=v;j++) if(dp[x][v-j]!=-1){ dp[x][v]=max(dp[x][v],dp[x][v-j]+dp[u][j]+(LL)(j*(k-j)+(sz[u]-j)*(n-sz[u]-k+j))*val[i]); } } }}int main(){ //freopen(".in","r",stdin); //freopen(".out","w",stdout); scanf("%d%d",&n,&k); for(int i=1;i
View Code

 

转载于:https://www.cnblogs.com/Achenchen/p/7524389.html

你可能感兴趣的文章
【hexo】01安装
查看>>
CI框架源码学习笔记2——Common.php
查看>>
005---书籍添加和编辑的提交数据
查看>>
使用case语句给字体改变颜色
查看>>
JAVA基础-多线程
查看>>
面试题5:字符串替换空格
查看>>
JSP九大内置对象及四个作用域
查看>>
ConnectionString 属性尚未初始化
查看>>
数据结构-栈 C和C++的实现
查看>>
发布功能完成
查看>>
MySQL基本命令和常用数据库对象
查看>>
poj 1222 EXTENDED LIGHTS OUT(位运算+枚举)
查看>>
秘密:之所以不搞军事同盟,俄罗斯
查看>>
进程和线程概念及原理
查看>>
Lucene、ES好文章
查看>>
后视镜应该这样用!能帮避免80%的车祸!
查看>>
PDB调试python代码常用命令
查看>>
web性能优化-浏览器渲染原理
查看>>
Java第七次作业
查看>>
配置consul为windows服务
查看>>