• [HAOI2015]树上染色


    题目描述(bzoj)

    同上(洛谷)

    思路

    树形DP
    size[i]:i子树的节点个数
    f[i][j]:在i子树中染j个黑点的最大贡献
    更新时考虑每条边对答案的贡献
    即:这条边两侧的黑点个数乘积*边权+两侧白点个数乘积*边权
    然后是注意开long long,要不然一半分就没了╮(╯_╰)╭

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define N 2005
    int n,k;
    struct edge{
        int u,v,nxt;
        long long dis;
    }e[N*2];
    int cnt,first[N];
    void add_edge(int x,int y,int z){
        e[++cnt].u=x;
        e[cnt].v=y;
        e[cnt].dis=z;
        e[cnt].nxt=first[x];
        first[x]=cnt;
    }
    bool vis[N];
    int size[N];
    long long f[N][N];
    long long calc(long long dis,int siz,int y){
        dis*=(y*(k-y)+(siz-y)*(n-k-siz+y));
        return dis;
    }
    void dfs(int u){
        vis[u]=true;
        size[u]=1;
        for(int i=first[u];i;i=e[i].nxt){
            int v=e[i].v;
            if(!vis[v]){
                dfs(v);
                for(int x=size[u];x>=0;x--){
                    for(int y=size[v];y>=0;y--){
                        long long sum=f[u][x]+f[v][y]+calc(e[i].dis,size[v],y);
                        f[u][x+y]=max(f[u][x+y],sum);
    //                    printf("when size[%d]=%d,f[%d][%d]=%d
    ",u,size[u],x,x+y,f[x][x+y]);
                    }
                }
                size[u]+=size[v];
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<n;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add_edge(x,y,z);
            add_edge(y,x,z);
        }
        dfs(1);
        long long ans=f[1][k];
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    .NET程序默认启动线程数
    TPL中Task执行的内联性线程重入
    Unity容器中的对象生存期管理
    C# 异步 TCP 服务器完整实现
    WPF中多源控制Button的状态
    C# 对 TCP 客户端的状态封装
    WPF异步MVVM等待窗体
    C#实现UDP分包组包
    C#实现RTP数据包传输
    PHP 传引用调用
  • 原文地址:https://www.cnblogs.com/aptx--4869/p/9813417.html
Copyright © 2020-2023  润新知