1. 程式人生 > >bzoj4033[HAOI2015] 樹上染色 dp

bzoj4033[HAOI2015] 樹上染色 dp

文章目錄

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