题意:在一棵树上,每条边都有权值,保留m条边,使留下来的总权值最大。
分析:很裸的树形DP,对于每一个节点,他的父节点可以选择给他分配0–m-1条边,取最大值即可。
代码如下:
#include <bits/stdc++.h>
using namespace std;
vector < int > q[110];
vector < int > w[110];
int f[300][300];
int n,Q;
void work(int son,int father) {
for(int i=0;i<q[son].size();i++) {
int s=q[son][i];
if(s==father) continue;//由于是无向图,所以如果搜到父亲就重新搜
work(s,son);//首先一层层递归到最底层后才开始工作
for(int j=Q;j>=0;j--) {
for(int k=j-1;k>=0;k--) {
f[son][j]=max(f[son][j],f[son][j-k-1]+f[s][k]+w[son][i]);//核心语句 为什么要是f[son][j-k-1]? 因为有1点花费在了边上,所以它能够传递下去的值就-1
}
}
}
return ;
}
int main() {
int a,b,c;
scanf("%d%d",&n,&Q);
for(int i=1;i<n;i++) {
scanf("%d%d%d",&a,&b,&c);
q[a].push_back(b);//由于是双向边所以存两次
q[b].push_back(a);
w[a].push_back(c);//w[i]用来存储边的价值
w[b].push_back(c);
}
work(1,0);
printf("%d",f[1][Q]);
return 0;
}
by:Chlince