前言
竟然是一道自己做出来的树形 d p \tt dp dp!
题目
思路
很简单(毕竟我都做出来了)。
设计 d p [ i ] [ 0 / 1 ] dp[i][0/1] dp[i][0/1] 为 i i i 号点是否选父边的答案,考虑转移即可。
Code
struct node
{
LL v, w;
node(){}
node(LL V,LL W)
{
v = V;
w = W;
}
};
vector<node> G[MAXN];
LL dp[MAXN][2], n, k;
bool cmp(LL x,LL y)
{
return x > y;
}
void Dfs(LL x,LL Fa)
{
vector<LL> Temp;
int l = G[x].size();
for (Int i = 0; i < l; ++ i)
{
LL to = G[x][i].v;
if (to == Fa)
continue;
Dfs(to, x);
dp[x][0] += dp[to][0], dp[x][1] += dp[to][0];
Temp.push_back(dp[to][1] + G[x][i].w - dp[to][0]);
}
sort(Temp.begin(), Temp.end(), cmp);
l = Temp.size();
for (Int i = 0; i < l && i < k; ++ i)
{
if (Temp[i] <= 0)
break;
if (i < k - 1)
dp[x][1] += Temp[i];
dp[x][0] += Temp[i];
}
}
int main()
{
LL T;
read( T );
while (T --)
{
read( n ); read( k );
for (Int i = 1; i < n; ++ i)
{
LL u, v, w;
read( u ); read( v ); read( w );
G[u].push_back(node(v, w));
G[v].push_back(node(u, w));
}
Dfs(1, 0);
printf("%lld\n", dp[1][0]);
for (Int i = 1; i <= n; ++ i)
G[i].clear(), dp[i][0] = dp[i][1] = 0;
}
return 0 ;
}