[HAOI2015] 树上染色
题目链接
树形DP
简要题意
思路
我们首先考虑如果
然后我们考虑如何在
而经过边
这启发我们如何算黑白点的贡献,设
那么经过边
那么对于边
/*
*/
#include <bits/stdc++.h>
using namespace std;
inline long long read(){
long long x=0,w=0;char c=0;
while(!isdigit(c)) {w|=c=='-';c=getchar();}
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
return w?-x:x;
}
long long n,k;
struct edge{
int to,nex;
long long w;
}e[4050];
int h[2050],cnt;
inline void add(int x,int y,int w){
e[++cnt]={y,h[x],w};
h[x]=cnt;
}
long long dis[2050];
long long dp[2050][2050],siz[2050],f[2050];
void dfs(int x,int fa){
siz[x]=1;
for(int i=h[x];i;i=e[i].nex){
int v=e[i].to;
if(v==fa){
continue;
}
dis[v]=dis[x]+e[i].w;
dfs(v,x);
for(int i=0;i<=k;i++){
f[i]=0;
}
for(int l=0;l<=min(siz[x],k);l++){
for(int j=0;j<=min(siz[v],k);j++){
if(l+j>k){
break;
}
f[l+j]=max(f[l+j],dp[x][l]+dp[v][j]+e[i].w*j*(k-j)+e[i].w*(siz[v]-j)*(n-k-siz[v]+j));
}
}
siz[x]+=siz[v];
for(int j=0;j<=min(siz[x],k);j++){
dp[x][j]=f[j];
}
}
}
int main(){
n=read();
k=read();
for(int i=1,x,y,z;i<n;i++){
x=read();
y=read();
z=read();
add(x,y,z);
add(y,x,z);
}
dfs(1,0);
printf("%lld",dp[1][k]);
return 0;
}
/*
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通