bzoj 树上染色
题意:
给定一棵n个点的树,把其中k个染成黑色,定义价值为黑色节点两两之间的距离和+白色节点两两之间的距离,求最大价值
分析:
树上dp
typedef pair<LL,LL> P;
LL N,K;
const LL maxn = 2000+10;
std::vector<P> G[maxn];
LL size[maxn];
LL dp[maxn][maxn];
LL tmp[maxn];
void dfs(LL node,LL fa){
// fill(dp,dp+N+1,)
size[node] = 1;
for(int i = 0;i < (int)G[node].size();++i){
P p = G[node][i];
LL c = p.first;
if(c == fa) continue;
dfs(c,node);
fill(tmp,tmp+1+N,0);
// 下面的操作是n^2 的
for(LL i = 0;i <= size[node]; ++i)
for(LL j = 0;j <= size[c]; ++j)
{
if(i+j <= K)
tmp[i+j] = max(tmp[i+j],dp[node][i]+dp[c][j]+1ll*p.second*(1ll*j*(K-j) + 1ll*(size[c]-j)*(N-size[c]-(K-j))));
}
size[node] += size[c];
for(LL i = 0;i <= K; ++i)
dp[node][i] = tmp[i];
}
}
int main(void)
{
cin>>N>>K;
LL u,v,w;
for(LL i= 1;i < N; ++i){
scanf("%lld%lld%lld",&u,&v,&w);
G[u].Pb(P(v,w));
G[v].Pb(P(u,w));
}
dfs(1,-1);
cout<<dp[1][K]<<endl;
return 0;
}