• HAOI树上染色


    Description :

    有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。

    Solution:

    这道题的思路很好,数据较强,可以看出这是道树形dp
    怎么设计状态呢?dp[x][j]表示以x为根的子树有j个点染成黑色的最大收获
    然后,然后就GG了
    原来这道题是考虑贡献,强啊
    状态改为以x的根的子树,有j个点染成黑色的最大贡献,这个贡献是对这个棵树而言的
    转移比较明显 枚举 j ,枚举子节点 的 黑色点数 k,直接dp即可
    注意枚举顺序,我们需要dp[x][j - k]未更新的贡献,就像01背包,一样倒序枚举j,正序枚举k,用j-k更新j,从更小的更新,它的阶段一定是上一个,不会出现自己更新自己,具有拓扑性
    注意边界:f[x][0]=f[x][1]=0;,不会出现成对的所以没有贡献

    #include <cstring>
    #include <cstdio>
    #include <iostream>
    
    using namespace std;
    
    const int MAXX = 2020;
    
    long long f[MAXX][MAXX];
    int hed[MAXX], ver[MAXX << 1], nxt[MAXX << 1], edge[MAXX << 1], siz[MAXX];
    int n, cnt, tot;
    
    inline void add(int x, int y,int z) {
      ver[++tot] = y;
      nxt[tot] = hed[x];
      hed[x] = tot;
      edge[tot] = z;
    }
    void dfs(int x, int fa) {
      siz[x] = 1;
      f[x][0] = f[x][1] = 0;
      for (int i = hed[x]; i; i = nxt[i]) {
        int y = ver[i];
        if (y == fa) continue;
        dfs(y,x);
        siz[x] += siz[y];
      }
      for (int i = hed[x]; i; i = nxt[i]) {
        int y = ver[i];
        if (y == fa) continue;
        for (int j = min(siz[x],cnt); j >= 0; --j) {
          for (int k = 0;k <= min(siz[y], j); ++k) {
            if(f[x][j - k] < 0) continue;
            long long val = (long long)k * (cnt - k) * edge[i] + (long long)(siz[y] - k) * (n - cnt - siz[y] + k) * edge[i];
            f[x][j] = max(f[x][j], f[x][j - k] + f[y][k] + val);
          }
        } 
      }
    }
    int main() {
      scanf("%d%d", &n, &cnt);
      for (int i = 1; i < n; ++i) {
        int x, y, z;
        scanf("%d%d%d",&x, &y, &z);
        add(x, y, z);
        add(y, x, z);
      }
      memset(f,-1,sizeof(f));
      dfs(1, 0);
      printf("%lld",f[1][cnt]);
      return 0;
    }
    
    

    %%%
    syt我是巨佬

  • 相关阅读:
    Commons JXPath
    10到十分精彩的智力题,你能过关几道?
    程序员下班电脑不关机的5大原因,你中招了吗?
    程序员下班电脑不关机的5大原因,你中招了吗?
    MySQL的一些概念笔记
    MySQL的一些概念笔记
    Shell中I/O重定向的用法笔记
    Shell中I/O重定向的用法笔记
    Shell重定向的概念笔记
    Shell重定向的概念笔记
  • 原文地址:https://www.cnblogs.com/ARTlover/p/9818264.html
Copyright © 2020-2023  润新知