[BZOJ4033][HAOI2015]树上染色 树形DP
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4033
我们考虑用记录以第个节点为根的子树,把个节点染成黑色对最终的答案的最大贡献。
在合并子树更新状态的时候,只需要考虑根与这棵子树的连边对最终答案的贡献即可,因为边的贡献只与两边点的数目有关。
注意更新状态时要像背包一样倒着更新。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef long long ll; 6 int inline readint(){ 7 int Num;char ch; 8 while((ch=getchar())<'0'||ch>'9');Num=ch-'0'; 9 while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0'; 10 return Num; 11 } 12 int N,K; 13 int to[4010],ne[4010],fir[2010],cnt=0; 14 ll w[4010]; 15 void Add(int a,int b,int c){ 16 to[++cnt]=b; 17 w[cnt]=c; 18 ne[cnt]=fir[a]; 19 fir[a]=cnt; 20 } 21 int siz[2010]; 22 ll f[2010][2010]; 23 void Dfs(int x,int fa){ 24 siz[x]=1; 25 f[x][0]=f[x][1]=0; 26 for(int i=fir[x];i!=-1;i=ne[i]){ 27 int v=to[i]; 28 if(v==fa) continue; 29 Dfs(v,x); 30 for(int j=siz[x];j>=0;j--) 31 for(int k=siz[v];k>=0;k--) 32 f[x][j+k]=max(f[x][j+k],f[x][j]+f[v][k]+w[i]*(K-k)*k+w[i]*(N-siz[v]-K+k)*(siz[v]-k)); 33 siz[x]+=siz[v]; 34 } 35 } 36 int main(){ 37 N=readint(); 38 K=readint(); 39 memset(fir,-1,sizeof(fir)); 40 for(int i=1;i<N;i++){ 41 int a=readint(), 42 b=readint(), 43 c=readint(); 44 Add(a,b,c); 45 Add(b,a,c); 46 } 47 Dfs(1,0); 48 printf("%lld\n",f[1][K]); 49 return 0; 50 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验