P2015 二叉苹果树
提交
15.30k
通过
7.27k
时间限制
1.00s
内存限制
125.00MB
提交答案
加入收藏
题目提供者
洛谷
难度
普及/提高-
历史分数
100
提交记录 查看题解
标签
进入讨论版
相关讨论
推荐题目
展开
题目描述
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,N和Q(1<=Q<= N,1<N<=100)。
N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式
一个数,最多能留住的苹果的数量。
输入输出样例
输入 #1复制
5 2
1 3 1
1 4 10
2 3 20
3 5 20
输出 #1复制
21
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#include <climits>
#include <stack>
#include <map>
#include <cmath>
#include <set>
#include <cstdlib>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
template<typename T>void write(T x)
{
if (x<0)
{
putchar('-');
x=-x;
}
if (x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
template<typename T> void read(T &x)
{
x = 0;char ch = getchar();ll f = 1;
while (!isdigit(ch)) {
if (ch == '-')f*=-1;ch=getchar();
}
while (isdigit(ch)){
x = x*10+ch-48;ch=getchar();
}x*=f;
}
const int maxn=150;
int head[maxn],dp[maxn][maxn];
int n,m,a,b,c;
struct node{
int to,next,w;
}e[maxn*2];
int tot,sz[maxn];
void add(int u,int v,int w){
e[++tot].to=v;
e[tot].w=w;
e[tot].next=head[u];
head[u]=tot;
}
void dfs(int u,int fa){
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(v==fa)continue;
dfs(v,u);
sz[u]+=sz[v]+1;
for(int j=min(sz[u],m);j>0;j--){
for(int k=min(sz[v],j-1);k>=0;k--){
dp[u][j]=max(dp[u][j],dp[u][j-k-1]+dp[v][k]+e[i].w);
}
}
}
}
int main() {
read(n);
read(m);
rep(i,1,n-1){
read(a);
read(b);
read(c);
add(a,b,c);
add(b,a,c);
}
dfs(1,0);
write(dp[1][m]);
return 0;
}