[HAOI2015] 树上染色

[题目链接]

          https://www.lydsy.com/JudgeOnline/problem.php?id=4033

[算法]

       树形背包

       时间复杂度 : O(N ^ 2)

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2010
typedef long long LL;

struct edge
{
    int to , w , nxt;
} e[MAXN << 1];

int n , m , tot;
int head[MAXN] , sz[MAXN];
LL dp[MAXN][MAXN];

template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
   T f = 1; x = 0;
   char c = getchar();
   for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
   for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
   x *= f;
}
inline void addedge(int u , int v , int w)
{
    ++tot;
    e[tot] = (edge){v , w , head[u]};
    head[u] = tot;
}
inline void dfs(int u , int fa)
{
    sz[u] = 1;
    dp[u][0] = dp[u][1] = 0;
    for (int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to;
        if (v == fa) continue;
        dfs(v , u);
        sz[u] += sz[v];
    }
    int cnt = 1;
    for (int i = head[u]; i; i = e[i].nxt)
    {
        int v = e[i].to , w = e[i].w;
        if (v == fa) continue;
        cnt += sz[v];
        for (int j = min(cnt , m); j >= 0; j--)
        {
            for (int k = 0; k <= min(sz[v] , j); k++)
            {
                if (dp[u][j - k] != -1)
                {
                    LL value = 1LL * (k * (m - k) + (sz[v] - k) * (n - sz[v] - (m - k))) * w;
                    dp[u][j] = max(dp[u][j] , dp[u][j - k] + dp[v][k] + value);
                }
            }
        }
    } 
}

int main()
{
    
    read(n); read(m);
    if (n - m < m) m = n - m;
    for (int i = 1; i < n; i++)
    {
        int u , v , w;
        read(u); read(v); read(w);
        addedge(u , v , w);
        addedge(v , u , w);
    }
    memset(dp , 255 , sizeof(dp));
    dfs(1 , 0);
    printf("%lld
" , dp[1][m]);
    
    return 0;
}
原文地址:https://www.cnblogs.com/evenbao/p/9879042.html