bzoj4033 [HAOI2015]树上染色——树形DP

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033

树形DP,状态中加入 x 与父亲之间的边的贡献;

边权竟然是long long...

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=2005;
int n,m,head[maxn],ct,siz[maxn];
long long f[maxn][maxn],ed[maxn];
struct N{
    int to,next;
    long long w;
    N(int t=0,int n=0,long long w=0):to(t),next(n),w(w) {}
}edge[maxn<<1]; 
void dfs(int x,int fa)
{
    siz[x]=1;
    for(int i=head[x],u;i;i=edge[i].next)
    {
        u=edge[i].to;
        if(u==fa)continue;
        ed[u]=edge[i].w;dfs(u,x);
        for(int j=min(siz[x],m);j>=0;j--)
            for(int k=min(siz[u],m-j);k>=0;k--)
                f[x][j+k]=max(f[x][j+k],f[u][k]+f[x][j]);
        siz[x]+=siz[u];
    }
    for(int i=0;i<=min(siz[x],m);i++)f[x][i]+=ed[x]*(i*(m-i)+(siz[x]-i)*(n-siz[x]-m+i));
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,x,y,z;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        edge[++ct]=N(y,head[x],z);head[x]=ct;
        edge[++ct]=N(x,head[y],z);head[y]=ct;
    }
    dfs(1,0);
    printf("%lld",f[1][m]);
    return 0;
}

 

posted @ 2018-06-10 08:56  Zinn  阅读(166)  评论(0编辑  收藏  举报