• [BZOJ 4033] [HAOI2015] T1 【树形DP】


    题目链接:BZOJ - 4033

    题目分析

    使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值。

    这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Father[i] 之间的边对答案的贡献(比如这条边对黑点对距离和的贡献就是子树内部的黑点数 * 子树外部的黑点数 * 这条边的权值)。

    然后DFS来求,枚举 i 的每个儿子 j,现在的 f[i][] 是包含了 [1, j-1] 子树,然后两重循环枚举范围是 [1, j - 1] 的子树总 Size 和 j 的 Size,来更新 f[i][],这样更新之后的 f[i][] 就是 [1, j] 子树的答案了。

    这样的更新看起来是 O(n^3) 的,但是其实可以看做枚举了任意点对的LCA,所以复杂度其实是 O(n^2) 的。

    代码

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long LL;
    
    inline int gmin(int a, int b) {return a < b ? a : b;}
    
    inline LL gmax(LL a, LL b) {return a > b ? a : b;}
    
    const int MaxN = 2000 + 5;
    
    int n, k;
    int Father[MaxN], Size[MaxN];
    
    struct Edge
    {
    	int v, w;
    	Edge *Next;
    } E[MaxN * 2], *P = E, *Point[MaxN];
    
    inline void AddEdge(int x, int y, int z)
    {
    	++P; P -> v = y; P -> w = z;
    	P -> Next = Point[x]; Point[x] = P;
    }
    
    LL Ans;
    LL Temp[MaxN], f[MaxN][MaxN];
     
    void Solve(int x, int Fa, int Num)
    {
    	Size[x] = 1;
    	for (Edge *j = Point[x]; j; j = j -> Next)
    	{
    		if (j -> v == Fa) continue;
    		Solve(j -> v, x, j -> w);
    		for (int i = 0; i <= gmin(Size[x], k); ++i) Temp[i] = f[x][i];
    		for (int p = 0; p <= gmin(Size[x], k); ++p)
    			for (int q = 0; q <= gmin(Size[j -> v], k); ++q)
    				f[x][p + q] = gmax(f[x][p + q], Temp[p] + f[j -> v][q]);
    		Size[x] += Size[j -> v];
     	}
     	for (int i = 0; i <= gmin(Size[x], k); ++i)
     		f[x][i] += (LL)Num * (LL)(i * (k - i) + (Size[x] - i) * (n - Size[x] - k + i));
    }
    
    int main()
    {
    	scanf("%d%d", &n, &k);
    	int x, y, z;
    	for (int i = 1; i <= n - 1; ++i)
    	{
    		scanf("%d%d%d", &x, &y, &z);
    		AddEdge(x, y, z); AddEdge(y, x, z);
    	}
    	Solve(1, 0, 0);
    	cout << f[1][k] << endl;
    	return 0;
    }
    

      

  • 相关阅读:
    判断分流使用
    Mac系统如何显示隐藏文件?
    Brew安装的软件查询安装位置
    JetBrains 产品线破解方法
    Linux查看与挂载新磁盘
    对BRD、MRD、PRD、FSD四类产品文档的理解
    网站收藏
    收藏
    官方文档
    java 的访问权限控制
  • 原文地址:https://www.cnblogs.com/JoeFan/p/4625272.html
Copyright © 2020-2023  润新知