• P3177 [HAOI2015]树上染色


    传送门

    显然考虑 $n^2$ 的树形 $dp$

    设 $f[x][i]$ 表示 $x$ 的子树内选了 $i$ 个节点染黑,子树内所有边对整颗树的最大贡献

    考虑子树的合并,显然对于 $(u,v),v in son[u]$ ,设边权为 $w$ ,这条边的贡献可以通过 $v$ 子树内的黑节点数算出

    因为确定了子树内的黑节点数就可以算出子树外的黑节点数,子树白节点也可以用子树节点数减去子树黑节点数得到

    那么贡献就容易确定

    那么对于 $f[u][i]$ ,枚举儿子 $v$ 并枚举 $v$ 内的黑节点数 $j$ ,有转移:

    $f[u][i]=max(f[u][i],f[u][i-j]+f[v][j]+wj(K-j)+w(sz[v]-j)(n-sz[v]-K+j))$

    注意代码实现的时候 $i$ 要从大到小枚举,并且 $j$ 要先把 $j=0$ 的情况转移好,才能保证 $f[u][i-j]$ 此时不包括 $v$ 的贡献

    这个代码实现的时候复杂度是 $n^2$ ,因为枚举当前的 $sz[x]$ 和下一个儿子 $v$ 的 $sz[v]$ 时枚举次数可以看成点对数(在 $v$ 内的点和在之前儿子子树的点)

    显然每个点对只会在 $lca$ 处枚举到

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2007;
    int n,m,sz[N];
    int fir[N],from[N<<1],to[N<<1],val[N<<1],cntt;
    inline void add(int a,int b,int c) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; val[cntt]=c; }
    ll f[N][N];
    void dfs(int x,int fa)
    {
        sz[x]=1; memset(f[x],-1,sizeof(f[x]));
        f[x][0]=f[x][1]=0;
        for(int i=fir[x];i;i=from[i])
        {
            int &v=to[i],&w=val[i]; if(v==fa) continue;
            dfs(v,x); sz[x]+=sz[v];
            for(int j=min(sz[x],m);j>=0;j--)
                for(int k=0;k<=min(sz[v],j);k++)//
                    if(f[x][j-k]>=0&&n-sz[v]>=m-k)
                        f[x][j]=max(f[x][j], f[x][j-k] + f[v][k] + 
                        1ll*w* ( k*(m-k) + (sz[v]-k)*(n-sz[v]-m+k) ) );
        }
    }
    int main()
    {
        n=read(),m=read(); int a,b,c;
        for(int i=1;i<n;i++)
        {
            a=read(),b=read(),c=read();
            add(a,b,c),add(b,a,c);
        }
        dfs(1,0);
        printf("%lld
    ",f[1][m]);
        return 0;
    }
  • 相关阅读:
    搭建微信小程序开发环境
    DOM 的classList 属性
    mui监听多个下拉刷新当前处于哪个选项卡
    mui常用功能链接地址
    css 弹性盒模型Flex 布局
    定义变量let,const
    微信小程序从零开始开发步骤(六)4种页面跳转的方法
    微信小程序从零开始开发步骤(五)轮播图
    展开符和解构赋值
    POJ 3660 Floyd传递闭包
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11751670.html
Copyright © 2020-2023  润新知