1. 程式人生 > >[HAOI2015] 樹上染色

[HAOI2015] 樹上染色

printf pac online 復雜度 head ref http dig efi

[題目鏈接]

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\n" , dp[1][m]); return 0; }

[HAOI2015] 樹上染色