题意
给你一棵树有个节点 然后给树上的个点将其染成黑色 然后剩下的染成白色 然后求黑点之间两两之间的距离加上白点之间两两之间的距离 求这个的最大值
树形 我们在的时候不仅仅时增加黑点的价值 还要处理出白点的价值
对于每条路径的贡献
$$
code
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); for (; !isdigit(ch); ch = getchar()) if (ch == '-') w = -1; for (; isdigit(ch); ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48); return s * w; } const int N = 2001; const int INF = 0x3f3f3f3f; int head[N] , ver[N << 2] , Next[N << 2] , edge[N << 2] , six[N]; int tot = 0; int n , m; ll f[N][N]; void add(int x , int y , int z){ ver[++tot] = y; edge[tot] = z; Next[tot] = head[x]; head[x] = tot; } void dfs1(int x , int fa){ six[x] = 1; for(int i = head[x] ; i ; i = Next[i]){ int y = ver[i]; if(y == fa) continue; dfs1(y , x); six[x] += six[y]; } } void dfs2(int x ,int fa){ f[x][0] = 0 , f[x][1] = 0; for(int i = head[x] ; i ; i = Next[i]){ int y = ver[i]; if(y != fa){ dfs2(y , x); for(int j = min(six[x] , m) ; j >= 0 ; --j){ for(int l = 0 ; l <= min(six[y] , j) ; ++l){ if(f[x][j - l] != -1){ ll val = 1ll * l * (m - l) * edge[i] + 1ll * (six[y] - l) * (n - m + l - six[y]) * edge[i]; f[x][j] = max(f[x][j - l] + f[y][l] + val , f[x][j]); } } } } } } void solve(){ n = read() , m = read(); for(int i = 1 ; i < n ; ++i){ int x = read() , y = read() , z = read(); add(x , y , z); add(y , x , z); } memset(f , -1 , sizeof(f)); dfs1(1 , 1); dfs2(1 , 1); cout<<f[1][m]<<endl; } int main(void){ solve(); return 0; }