codeforces 802K Send the Fool Further! (medium) 树形dp

K. Send the Fool Further! (medium)
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Thank you for helping Heidi! It is now the second of April, but she has been summoned by Jenny again. The pranks do not seem to end...

In the meantime, Heidi has decided that she does not trust her friends anymore. Not too much, anyway. Her relative lack of trust is manifested as follows: whereas previously she would not be made to visit the same person twice, now she can only be sure that she will not be made to visit the same person more than k times. (In the case of Jenny, this includes her first visit in the beginning. The situation from the easy version corresponds to setting k = 1.)

This is not as bad as it looks, since a single ticket for a route between two friends allows Heidi to travel between this pair of friends the whole day (in both directions). In other words, once she pays for travel between a pair of friends, all further travels between that pair are free.

How much money will Heidi waste now, in a worst-case scenario?

Input

The first line contains two space-separated integers – the number of friends n () and the parameter k (1 ≤ k ≤ 105). The next n - 1 lines each contain three space-separated integers uv and c (0 ≤ u, v ≤ n - 11 ≤ c ≤ 104) meaning that u and v are friends and the cost for traveling between u and v is c.

It is again guaranteed that the social network of the input forms a tree.

Output

Again, output a single integer – the maximum sum of costs of tickets.

Examples
input
9 3
0 1 1
0 2 1
1 3 2
1 4 2
1 5 2
2 6 3
2 7 3
2 8 3
output
15
input
9 5
0 1 1
0 2 1
1 3 2
1 4 2
1 5 2
2 6 3
2 7 3
2 8 3
output
17
input
11 6
1 0 7932
2 1 1952
3 2 2227
4 0 9112
5 4 6067
6 0 6786
7 6 3883
8 4 7137
9 1 2796
10 5 6200
output
54092
Note

In the first example, the worst-case scenario for Heidi is to visit the friends in the following order: 0, 1, 5, 1, 3, 1, 0, 2, 6, 2, 7, 2, 8. Observe that no friend is visited more than 3 times.


题目大概意思是这样的。。是给定一棵树,每条边上有一个宝物价值为w,每个节点最多访问k次,求能得到的最大价值
dp[u][1]表示访问完以u为根的子树并且返回到u的父节点fa所得到的最大价值
dp[u][0]表示访问完以u为根的子树并且不返回到u的父节点fa而是停在这棵子树内部所得到的最大价值

#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <cstring>

using namespace std;
const int maxn = 1e5 + 10;
int N, K;
int cnt, head[maxn], dp[maxn][2];

struct E
{
	int v, w, next;
}G[maxn * 2];

void add(int u, int v, int w)
{
	G[cnt].v = v;
	G[cnt].w = w;
	G[cnt].next = head[u];
	head[u] = cnt++;
}

void dfs(int u, int p, int last)
{
	dp[u][0] += last;
	dp[u][1] += last;
	vector< pair<int, int> > tmp;
	for (int i = head[u]; i != -1; i = G[i].next)
	{
		int v = G[i].v;
		int w = G[i].w;
		if (v == p) continue;
		dfs(v, u, w);
		tmp.push_back(make_pair(dp[v][1], v));
	}
	sort(tmp.begin(), tmp.end());
	reverse(tmp.begin(), tmp.end());

	int ans = 0;
	int max_tmp = 0;
	for (int i = 0; i < K - 1 && i < tmp.size(); i++) {
		dp[u][1] += tmp[i].first;
	} 
	for (int i = 0; i < K && i < tmp.size(); i++) ans = ans + tmp[i].first;
	for (int i = 0; i < tmp.size(); i++)
	{
		if (i < K)
			max_tmp = max(max_tmp, ans - tmp[i].first + dp[tmp[i].second][0]);
		else
			max_tmp = max(max_tmp, ans - tmp[K - 1].first + dp[tmp[i].second][0]);
	}
	dp[u][0] += max_tmp;
}

int main()
{
	cnt = 0;
	memset(head, -1, sizeof(head));
	memset(dp, 0, sizeof(dp));
	scanf("%d%d", &N, &K);
	for (int i = 1; i < N; i++)
	{
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w);
		add(v, u, w);
	}
	dfs(0, -1, 0);
	printf("%d\n", dp[0][0]);

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值