奆佬求助
查看原帖
奆佬求助
823773
_sh1kong_楼主2023/2/23 21:30

RT,31pts

#include <iostream>

const int N = 1001;

using namespace std;

int n, q;

int x, y, c, tot;

int h[N], e[N], ne[N], to[N], f[N][N];

int ls[N], rs[N], lapp[N], rapp[N];

//f[i][j] 表示以 i 为根节点 保留 j 根树枝时的最大值 

void add(int x, int y, int z)

{
	ne[++ tot] = h[x];
	h[x] = tot;
	e[tot] = z;
	to[tot] = y;
} 

void build(int x, int fa)//当前节点 父亲节点

{
    int cnt = 0;
    for (int i = h[x]; i; i = ne[i])
    {
        int s = to[i];
        if (s != fa)
        {
            cnt ++;
            if (cnt == 1) ls[x] = s, lapp[x] = e[i];
            else rs[x] = s, rapp[x] = e[i];
            build(s, x);
        }
    }
}

int find(int x, int j)

{
    if (ls[x] == 0 && rs[x] == 0) return 0;
    if (j == 0) return 0;
    if (f[x][j] > 0) return f[x][j];
    for (int k = 0; k <= j; k ++ )//分配给左儿子的枝数 k
    {
        if (k == 0) f[x][j] = max(f[x][j], find(rs[x], k - 1) + rapp[x]);//全部给右
        else if (k == j) f[x][j] = max(f[x][j], find(ls[x], k - 1) + lapp[x]);//全部给左
        else f[x][j] = max(f[x][j], find(ls[x], k - 1) + lapp[x] + find(rs[x], j - k - 1) + rapp[x]);//两边都有
    }
    return f[x][j];
}

int main()

{
	cin >> n >> q;
	for (int i = 1; i <= n - 1; i ++ )
	{
		cin >> x >> y >> c;
		add(x, y, c);
		add(y, x, c);//惊现yxc 
	}
	build(1, 0);
	cout << find(1, q) << endl;
}

2023/2/23 21:30
加载中...