bzoj4033[HAOI2015] 树上染色 dp

探讨了在给定的树结构中,如何通过树上动态规划算法,找到将k个节点染为黑色以最大化黑色节点间距离和与白色节点间距离之和的方法。

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值