题意
给你一棵树有个节点 然后给树上的
个点将其染成黑色 然后剩下的染成白色 然后求黑点之间两两之间的距离加上白点之间两两之间的距离 求这个的最大值
树形 我们在
的时候不仅仅时增加黑点的价值 还要处理出白点的价值
对于每条路径的贡献
$$
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;
} 
京公网安备 11010502036488号