P3177 [HAOI2015]树上染色

Description

有一棵点数为 N 的树,树边有边权。给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 。 将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间的距离的和的受益。问受益最大值是多少。

Solution

\(f_{i,j}\)表示\(i\)个点选择\(j\)个黑点的最大收益.

Code

#include <cstdio>
#include <cstring>
#include <iostream>
#define N 2005
using namespace std;
#define int long long

struct Edge {
    int v, dis, nxt;
} e[N << 1];
int head[N], tot;

void AddEdge(int u, int v, int d) {
    e[++tot] = (Edge) {v, d, head[u]}; head[u] = tot;
    e[++tot] = (Edge) {u, d, head[v]}; head[v] = tot;
}
int son[N], f[N][N];
int n, k;

int find(int u, int fa) {
    son[u] = 1; f[u][0] = f[u][1] = 0;
    for (int i = head[u]; i; i = e[i].nxt) {
        if (e[i].v == fa)continue;
        son[u] += find(e[i].v, u);
        for (int ss = min(son[u], k); ss >= 0; --ss)
            for (int j = 0; j <= min(son[e[i].v], ss); ++j) {
                f[u][ss] = max(f[u][ss], f[u][ss - j] + f[e[i].v][j] +
                    (j * (k - j) + (son[e[i].v] - j) * (n - k + j - son[e[i].v])) * e[i].dis);
            }
    }
    return son[u];
}

main() {
    int u, v, d;
    scanf("%lld%lld", &n, &k);
    for (int i = 1; i < n; ++i) {
        scanf("%lld%lld%lld", &u, &v, &d);
        AddEdge(u, v, d);
    }
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= k; ++j)
            f[i][j] = -123456789;
    find(1, 0);
    printf("%lld\n", f[1][k]);
    return 0;
}

转载于:https://www.cnblogs.com/qdscwyy/p/9790685.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值