码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4033: [HAOI2015]树上染色

时间:2018-05-26 10:52:21      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:memset   turn   树形背包   scanf   add   http   void   scan   莫名其妙   

题目链接

bzoj4033: [HAOI2015]树上染色

题解

对与每条边贡献dp,树形背包
然后开始写成了每条边对于子树的贡献,然后写挂了别的地方,然后lg上莫名其妙的过了许多别的点
然后发现似乎神奇的性质...有空出道题2333
bzoj有些卡常数

代码

#include<cstdio>
#include<cstring> 
#include<algorithm> 
  
#define LL long long 
int n,K; 
const int maxn = 2007; 
struct node { 
    int v,w,next; 
} edge[maxn << 1]; 
int num = 0,head[maxn],size[maxn];  
inline void add_edge(int u,int v,int w) { 
    edge[++ num].v = v,edge[num].next = head[u];edge[num].w = w; head[u] = num; 
}  
LL dp[maxn][maxn];  
void dfs(int x,int fa) {  
    size[x] = 1;dp[x][0] = dp[x][1] = 0; 
    for(int i = head[x];i;i = edge[i].next) { 
        int v = edge[i].v; 
        if(v == fa) continue;  dfs(v,x); size[x] += size[v]; 
    } 
    for(int i = head[x];i;i = edge[i].next) { 
    int v = edge[i].v; 
        if(v == fa)continue; 
        for(int j = std::min(size[x],K);j >= 0;-- j) { 
        for(int k = 0;k <= std::min(j,size[v]);++ k) {
                    if(dp[x][j - k] >= 0) {
                    LL tmp = (LL)k * (K - k) * edge[i].w + (LL)(n - K - (size[v] - k)) * (size[v] - k) * edge[i].w;         
                    dp[x][j] = std::max(dp[x][j - k] + dp[v][k] + tmp,dp[x][j]);   
            }    
        } 
        } 
    } 
} 
int main() { 
    memset(dp,-1,sizeof dp); 
    scanf("%d%d",&n,&K); 
    for(int u,v,w,i = 1;i < n;++ i) { 
        scanf("%d%d%d",&u,&v,&w);
        add_edge(u,v,w);
        add_edge(v,u,w); 
    } 
    dfs(1,0); 
    printf("%lld\n",dp[1][K]); 
    return 0; 
} 

bzoj4033: [HAOI2015]树上染色

标签:memset   turn   树形背包   scanf   add   http   void   scan   莫名其妙   

原文地址:https://www.cnblogs.com/sssy/p/9091566.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!