# Luogu3177 [HAOI2015]树上染色

## Solution

$dp[u][j + k] \leftarrow dp[u][j] + dp[v][k] + val$

## Code

#include <bits/stdc++.h>

using namespace std;

#define fst first
#define snd second
#define mp make_pair
#define squ(x) ((LL)(x) * (x))
#define debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef pair<int, int> pii;

template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }

int sum = 0, fg = 1; char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') fg = -1;
for (; isdigit(c); c = getchar()) sum = (sum << 3) + (sum << 1) + (c ^ 0x30);
return fg * sum;
}

const int maxn = 2e3 + 10;

int Begin[maxn], Next[maxn << 1], To[maxn << 1], w[maxn << 1], e;
inline void link(int x, int y, int z) { To[++e] = y, Next[e] = Begin[x], Begin[x] = e, w[e] = z; }

int n, m, sz[maxn];
LL dp[maxn][maxn];

inline void dfs(int now, int f) {
int lim = 1;
for (int i = Begin[now]; i; i = Next[i]) {
int son = To[i];
if (son == f) continue;
dfs(son, now);
for (int j = min(lim, m); ~j; j--)
for (int k = min(sz[son], m); ~k; k--)
if (j + k <= m)
chkmax(dp[now][j + k], dp[now][j] + dp[son][k] + (LL) w[i] * (k * (m - k) + (sz[son] - k) * (n - m - sz[son] + k)));
lim += sz[son];
}
sz[now] = lim;
}

int main() {
#ifdef xunzhen
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
#endif

}