• 【Luogu】P3177树上染色(树形DP)


      题目链接

      题没想出来很烦+一堆细节要注意很烦。

      当然更可能是我智商被osu吃了。

      考虑一条边会有什么贡献?它一边的黑点数*另一边的黑点数*边权。

      +它一边的白点数*另一边的白点数*边权。

      这样一来就成了一个树形背包

      

    #include<cstring>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    #define maxn 2030
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Edge{
        long long next,to,dis;
    }edge[maxn*3];
    long long head[maxn],num;
    inline void add(long long from,long long to,long long dis){
        edge[++num]=(Edge){head[from],to,dis};
        head[from]=num;
    }
    
    long long n,m;
    long long size[maxn];
    long long f[maxn][maxn];
    
    void build(long long x,long long fa){
        size[x]=1;
        for(long long i=head[x];i;i=edge[i].next){
            long long to=edge[i].to;
            if(to==fa)    continue;
            build(to,x);
            size[x]+=size[to];
        }
    }
    
    inline long long calc(long long i,long long x){
        return (m-x)*x*edge[i].dis+(n-m+x-size[edge[i].to])*(size[edge[i].to]-x)*edge[i].dis;
    }
    
    void dfs(long long x,long long fa){
        memset(f[x],-1,sizeof(f[x]));    f[x][0]=f[x][1]=0;
        for(long long i=head[x];i;i=edge[i].next){
            long long to=edge[i].to;
            if(to==fa)    continue;
            dfs(to,x);
            for(long long j=min(m,size[x]);j>=0;--j){
                for(long long k=0;k<=min(j,size[to]);++k)
                    if(f[x][j-k]!=-1)    f[x][j]=max(f[x][j],f[x][j-k]+f[to][k]+calc(i,k));
            }
        }
        return;
    }
    
    int main(){
        n=read(),m=read();
        for(long long i=1;i<n;++i){
            long long from=read(),to=read(),dis=read();
            add(from,to,dis);
            add(to,from,dis);
        }
        build(1,1);
        dfs(1,1);
        printf("%lld
    ",f[1][m]);
        return 0;
    }
  • 相关阅读:
    终于找到一个在IE8下可以使用搜索栏的输入法了
    在psp中播放电脑上的flv文件
    屏蔽红警3强制升级
    在windows7中安装了office了
    Flv视频编辑软件FlvEditor
    射杀恋人之日
    USB口不够用了
    年底了,游戏大作连连
    又一个好用的xbox360手柄驱动
    Windows7体验小记
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8342623.html
Copyright © 2020-2023  润新知