bzoj4033 [HAOI2015]树上染色——树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033
树形DP,状态中加入 x 与父亲之间的边的贡献;
边权竟然是long long...
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int const maxn=2005; int n,m,head[maxn],ct,siz[maxn]; long long f[maxn][maxn],ed[maxn]; struct N{ int to,next; long long w; N(int t=0,int n=0,long long w=0):to(t),next(n),w(w) {} }edge[maxn<<1]; void dfs(int x,int fa) { siz[x]=1; for(int i=head[x],u;i;i=edge[i].next) { u=edge[i].to; if(u==fa)continue; ed[u]=edge[i].w;dfs(u,x); for(int j=min(siz[x],m);j>=0;j--) for(int k=min(siz[u],m-j);k>=0;k--) f[x][j+k]=max(f[x][j+k],f[u][k]+f[x][j]); siz[x]+=siz[u]; } for(int i=0;i<=min(siz[x],m);i++)f[x][i]+=ed[x]*(i*(m-i)+(siz[x]-i)*(n-siz[x]-m+i)); } int main() { scanf("%d%d",&n,&m); for(int i=1,x,y,z;i<n;i++) { scanf("%d%d%d",&x,&y,&z); edge[++ct]=N(y,head[x],z);head[x]=ct; edge[++ct]=N(x,head[y],z);head[y]=ct; } dfs(1,0); printf("%lld",f[1][m]); return 0; }