HYSBZ-4033-树上染色(树上DP)
链接:
https://vjudge.net/problem/HYSBZ-4033
题意:
有一棵点数为N的树,树边有边权。给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并
将其他的N-K个点染成白色。将所有点染色后,你会获得黑点两两之间的距离加上白点两两之间距离的和的收益。
问收益最大值是多少。
思路:
数上任意两点的距离,每条边e(u,v)的贡献是cntl[u], cntr[v], 就是u左边的点乘上v右边的点乘上权值.
同时令DP[u][k]为u的子树中有k个黑点,的最大值.
在DFS中从u到v可推出Dp[u][i+j] = max(Dp[u][i+j], Dp[u][j]+Dp[v][i]+dis*cnt)其中Dp[u][j]为以u为根,别的边的贡献.
Dp[v][i]表示此条边连着的v的子数的贡献,最后算出这条边的贡献.
cnt就是两端黑白的组合数.
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
//#include <memory.h>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#include <string>
#include <assert.h>
#include <iomanip>
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 2e3+10;
struct Node
{
int to;
LL dis;
};
vector<Node> G[MAXN];
LL Dp[MAXN][MAXN];
int Cnt[MAXN];
int n, k;
void Dfs(int u, int v)
{
Cnt[v] = 1;
for (int i = 0;i < G[v].size();i++)
{
int node = G[v][i].to;
if (node == u)
continue;
Dfs(v, node);
for (int j = min(Cnt[v], k);j >= 0;j--)
{
for (int z = min(Cnt[node], k);z >= 0;z--)
{
LL ti = 1LL*z*(k-z)+1LL*(Cnt[node]-z)*(n-Cnt[node]-(k-z));
Dp[v][j+z] = max(Dp[v][j+z], Dp[v][j]+Dp[node][z]+G[v][i].dis*ti);
}
}
Cnt[v] += Cnt[node];
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> k;
int u, v;
LL w;
for (int i = 1;i < n;i++)
{
cin >> u >> v >> w;
G[u].push_back(Node{v, w});
G[v].push_back(Node{u, w});
}
Dfs(0, 1);
cout << Dp[1][k] << endl;
return 0;
}
HYSBZ-4033-树上染色(树上DP)的更多相关文章
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- bzoj 4033: [HAOI2015]树上染色 [树形DP]
4033: [HAOI2015]树上染色 我写的可是\(O(n^2)\)的树形背包! 注意j倒着枚举,而k要正着枚举,因为k可能从0开始,会使用自己更新一次 #include <iostream ...
- [BZOJ4033][HAOI2015]树上染色(树形DP)
4033: [HAOI2015]树上染色 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2437 Solved: 1034[Submit][Stat ...
- 【BZOJ4033】[HAOI2015]树上染色 树形DP
[BZOJ4033][HAOI2015]树上染色 Description 有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染 ...
- [HAOI2015]树上染色(树上dp)
[HAOI2015]树上染色 这种要算点对之间路径的长度和的题,难以统计每个点的贡献.这个时候一般考虑算每一条边贡献了哪些点对. 知道这个套路以后,那么这题就很好做了. 状态:设\(dp[u][i]\ ...
- 【HAOI2015】树上染色—树形dp
[HAOI2015]树上染色 [题目描述]有一棵点数为N的树,树边有边权.给你一个在0~N之内的正整数K,你要在这棵树中选择K个点,将其染成黑色,并将其他的N-K个点染成白色.将所有点染色后,你会获得 ...
- 【BZOJ】4033: [HAOI2015]树上染色 树上背包
[题目]#2124. 「HAOI2015」树上染色 [题意]给定n个点的带边权树,要求将k个点染成黑色,使得 [ 黑点的两两距离和+白点的两两距离和 ] 最大.n<=2000. [算法]树上背包 ...
- BZOJ 4033 [HAOI2015]树上染色 ——树形DP
可以去UOJ看出题人的题解. 这样的合并,每一个点对只在lca处被考虑到,复杂度$O(n^2)$ #include <map> #include <ctime> #includ ...
- bzoj4033 [HAOI2015]树上染色——树形DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4033 树形DP,状态中加入 x 与父亲之间的边的贡献: 边权竟然是long long... ...
- 【HAOI2015】树上染色 - 树形 DP
题目描述 有一棵点数为 N 的树,树边有边权.给你一个在 0~ N 之内的正整数 K ,你要在这棵树中选择 K个点,将其染成黑色,并将其他 的N-K个点染成白色 . 将所有点染色后,你会获得黑点两两之 ...
随机推荐
- Java学习之==>注解
一.概述 关于注解,首先引入官方文档的一句话:Java 注解用于为 Java 代码提供元数据.作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的.接下我将从注解的定义. ...
- Web02_HTML&CSS
HTML 表单标签属性介绍 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- Elastic search中使用nested类型的内嵌对象
在大数据的应用环境中,往往使用反范式设计来提高读写性能. 假设我们有个类似简书的系统,系统里有文章,用户也可以对文章进行赞赏.在关系型数据库中,如果按照数据库范式设计,需要两张表:一张文章表和一张赞赏 ...
- springboot--websocket简单demo(一):session chat
最近跟着大佬 https://tycoding.cn/2019/06/16/project/boot-chat/ 敲了2个关于websocket的demo,总结一下 从将会话信息保存在session中 ...
- Python学习之协程
8.8 协程 我们都知道线程间的任务切换是由操作系统来控制的,而协程的出现,就是为了减少操作系统的开销,由协程来自己控制任务的切换 协程本质上就是线程.既然能够切换任务,所以线程有两个最基本的 ...
- LeetCode.917-只反转字母(Reverse Only Letters)
这是悦乐书的第353次更新,第378篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第215题(顺位题号是917).给定一个字符串S,返回"反向"字符串 ...
- Java 8中处理集合的优雅姿势——Stream
在Java中,集合和数组是我们经常会用到的数据结构,需要经常对他们做增.删.改.查.聚合.统计.过滤等操作.相比之下,关系型数据库中也同样有这些操作,但是在Java 8之前,集合和数组的处理并不是很便 ...
- AES ------ 第三方库
tiny-AES-c-master.zip 这个库可用
- Neo4j下载与使用
Neo4j 官网 : https://neo4j.com/ Neo4j 国内: http://neo4j.com.cn/topic/5b003eae9662eee704f31cee http://we ...
- Leetcode 35.搜索插入位置 By Python
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引.如果目标值不存在于数组中,返回它将会被按顺序插入的位置. 你可以假设数组中无重复元素. 示例 1: 输入: [1,3,5,6], 5 输 ...