zoukankan      html  css  js  c++  java
  • [HAOI2015]树上染色(树形dp)

    传送门

    这道题还是打一下,毕竟也是一道比较经典的题。

    思想值得学习:求点两两之间的距离和不如转化成看一条边会对哪些点对做出贡献。

    下面以黑点为例,白点同理。

    那么对于一条边(x,y)

    根据乘法原理:它对黑点距离的贡献即为y子树内的黑点点数 * y子树外的黑点点数。

    于是我们就要对点分配哪些点为黑点,转化为树上背包问题。

    然后有一点值得注意,在代码内有注释。

    #include<bits/stdc++.h>
    #define LL long long 
    #define N 2003
    using namespace std;
    int read()
    {
        int x=0,f=1;char s=getchar();
        while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
        while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
        return x*f;
    }
    void print(int x)
    {
        if(x<0)x=-x,putchar('-');
        if(x>9)print(x/10);
        putchar(x%10+'0');
    }
    struct EDGE{
        int nextt,to,dis;
    }w[N*2];
    int n,K;
    int tot=0;
    int head[N],siz[N];
    LL f[N][N];
    void add(int a,int b,int c)
    {
        tot++;
        w[tot].nextt=head[a];
        w[tot].to=b;
        w[tot].dis=c;
        head[a]=tot;
    }
    void dfs(int x,int fa)
    {
        siz[x]=1;f[x][0]=f[x][1]=0;
        for(int i=head[x];i;i=w[i].nextt)
        {
            int v=w[i].to;
            if(v==fa)continue;
            dfs(v,x);
            siz[x]+=siz[v];
            for(int j=min(K,siz[x]);j>=0;--j)
            {
                if(f[x][j]!=-1)
                  f[x][j]+=f[v][0]+(LL)siz[v]*(n-K-siz[v])*w[i].dis;
                //正序转移和倒序转移在本质上并没有差别,但是在这道题中,对于当前枚举的子节点的子树,哪怕一个黑点也没有,
                //它仍然可以对答案产生贡献,所以我们要先算上这种情况的贡献,否则在接下来的转移中,就会少计算本来就有的价值
                for(int k=min(j,siz[v]);k;--k)
                {
                    if(f[x][j-k]==-1)continue;
                    LL val=(LL)(k*(K-k)+(siz[v]-k)*(n-K-siz[v]+k))*w[i].dis;
                    f[x][j]=max(f[x][j],f[x][j-k]+f[v][k]+val);
                }
            }
        }
    }
    int main()
    {
        n=read();K=read();
        for(int i=1;i<n;++i)
        {
            int a=read(),b=read(),c=read();
            add(a,b,c);add(b,a,c);
        }
        memset(f,-1,sizeof(f));
        dfs(1,1);
        printf("%lld
    ",f[1][K]);
    }
    /*
    */
    View Code
  • 相关阅读:
    iOS
    “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift
    iOS
    iOS
    springboot rabbitmq 死信队列应用场景和完整demo
    LRU
    分布式系统高可用原则
    Java8 Stream 流使用场景和常用操作
    下载安装Zookeeper
    Java8内置的函数式编程接口应用场景和方式
  • 原文地址:https://www.cnblogs.com/yyys-/p/11844833.html
Copyright © 2011-2022 走看看