题解:
树形DP
思路,考虑每条边的贡献,即这条边两边的黑点数量相乘+白点数量相乘再成边长
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=2009; typedef long long Lint; int n,m; int cntedge=0; int head[maxn]={0}; int to[maxn<<1],nex[maxn<<1],dist[maxn<<1]; void Addedge(int x,int y,int z){ nex[++cntedge]=head[x]; to[cntedge]=y; dist[cntedge]=z; head[x]=cntedge; } Lint f[maxn][maxn]; Lint g[maxn]; int siz[maxn]; void Dp(int x,int fa){ for(int i=head[x];i;i=nex[i]){ int v=to[i]; if(to[i]==fa)continue; Dp(v,x); memset(g,0,sizeof(g)); for(int j=0;j<=siz[x];++j){ for(int k=0;k<=siz[v];++k){ Lint tm=max(f[v][k],k?f[v][k-1]:0)+f[x][j]+1LL*k*(m-k)*dist[i]+1LL*(siz[v]-k)*(n-m-siz[v]+k)*dist[i]; g[j+k]=max(g[j+k],tm); } } siz[x]+=siz[v]; for(int j=0;j<=siz[x];++j)f[x][j]=g[j]; } ++siz[x]; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n-1;++i){ int x,y,z; scanf("%d%d%d",&x,&y,&z); Addedge(x,y,z); Addedge(y,x,z); } Dp(1,0); cout<<max(f[1][m],f[1][m-1]); cout<<endl; return 0; }
原文地址:https://www.cnblogs.com/zzyer/p/8560983.html
时间: 2024-10-22 14:01:54