Game HDU - 5242 树链思想
GameHDU - 5242
题目大意:一个游戏有n个场景形成了棵有根树,根节点是1,每个场景都有它的权值。然后一个人可以选择其中K个分支来走,而每个场景的权重只算一遍,问最大的权值和。
一开始想叉了,觉得是树形dp加背包,然后好麻烦就不懂写了,但其实根本没有那么难。就是用到了个树链的思想,把整棵树分成一条条链,这样就没有了重复部分,然后就是从中取k条权值和最大的链。
具体操作类似于树链剖分的分链处理(想起来树链剖分拖了很久没更,这两天更上)。如果不知道重链和重儿子是什么,可以先去学一下。在原来的定义里,重儿子是儿子节点中子树节点个数最多的节点,而我们这题就定义为儿子节点中拥有链权值和最大的那个节点。比如在样例1中
2的重儿子就是3,而1的重儿子是2,这样就有1到3一条重链,加上4到4,5到5,3条链。然后我们把不是链顶部的节点权值清空(在上图中就是2和3),最后把所有节点权值,挑选k个最大的。
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=;
struct Side{
int v,ne;
}S[N];
ll val[N];
int sn,head[N],son[N];
void init(int n)
{
sn=;
for(int i=;i<=n;i++)
{
head[i]=-;
son[i]=;
}
}
void add(int u,int v)
{
S[sn].v=v;
S[sn].ne=head[u];
head[u]=sn++;
}
void dfs1(int u)
{
for(int i=head[u];i!=-;i=S[i].ne)
{
int v=S[i].v;
dfs1(v);//题目是单向边,不用在判断v是不是u的父亲
if(val[v]>val[son[u]])
son[u]=v;
}
val[u]+=val[son[u]];//把它重儿子的权值算到它这里
}
void dfs2(int u,int tf)
{
if(u!=tf)
val[u]=;//不是链的顶端,权值清空
if(!son[u])
return ;
dfs2(son[u],tf);
for(int i=head[u];i!=-;i=S[i].ne)
{
int v=S[i].v;
if(v!=son[u])
dfs2(v,v);
}
}
int main()
{
int t=,T,n,k,u,v;
scanf("%d",&T);
while(t<=T)
{
scanf("%d%d",&n,&k);
init(n);
for(int i=;i<=n;i++)
scanf("%lld",&val[i]);
for(int i=;i<n-;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
dfs1();
dfs2(,);
sort(val+,val++n);
ll ans=;
for(int i=n;i>=&&k;i--,k--)
{
if(!val[i])
break;
ans+=val[i];
}
printf("Case #%d: %lld\n",t++,ans);
}
return ;
}
多理解多想想
Game HDU - 5242 树链思想的更多相关文章
- HDU 5242 树链剖分思想的贪心
题意及博客 树链剖分分为2步,第一次求出深度,重儿子,第二次求出重链,用到了启发式的思想,即对于比较重的儿子,尽量去完整的维护它.类似于我们去合并两个堆,明显把小的堆逐个插入大的堆中会比大的往小的插更 ...
- hdu 5893 (树链剖分+合并)
List wants to travel Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/O ...
- hdu 5052 树链剖分
Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- hdu 4897 树链剖分(重轻链)
Little Devil I Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others ...
- hdu 5274 树链剖分
Dylans loves tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 3966 (树链剖分+线段树)
Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- HDU 3966 /// 树链剖分+树状数组
题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...
- hdu 4729 树链剖分
思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...
随机推荐
- 老贾的幸福生活day6 整型和布尔值的转换 字符串讲解 for 循环简介
整型和布尔值的转换: 整型: python 2 整型 int long(长整型) /获取的是整型 python 3 整型 int 获取的是浮点数(小数) 十进制转二进制: print(bin(36)) ...
- 深入理解Python中的GIL(全局解释器锁)
深入理解Python中的GIL(全局解释器锁) Python是门古老的语言,要想了解这门语言的多线程和多进程以及协程,以及明白什么时候应该用多线程,什么时候应该使用多进程或协程,我们不得不谈到的一个东 ...
- CentOS7下使用ELK搭建日志集中分析平台
应用场景: ELK实际上是三个工具的集合,ElasticSearch + Logstash + Kibana,这三个工具组合形成了一套实用.易用的监控架构,很多公司利用它来搭建可视化的海量日志分析平台 ...
- css多种方式实现等宽布局
本文讲的等宽布局是在不手动设置元素宽度的情况下,使用纯css实现各个元素宽度都相当的效果. 1.使用table-cell实现(兼容ie8) <style> body,div{ margin ...
- Java IO与NIO的总结、比较
一.IO流总结 1.Java I/O主要包括如下3层次: 流式部分——最主要的部分.如:OutputStream.InputStream.Writer.Reader等 非流式部分——如:File类.R ...
- jenkins 设置中文显示
这里使用的方法是安装中文语言包,安装的插件名称是:Localization: Chinese (Simplified) 1.在插件管理,搜索 Localization: Chinese (Simpli ...
- 树莓派3B+和3B 安装64位debian GUN/Linux系统
请直接参考如下博客: https://blog.csdn.net/u013451404/article/details/80710136 如果是3B的树莓派用户,只需要把第一个分区boot里的.dtb ...
- WCF寄宿windows服务二
如果有很多WCF服务需要寄宿,需要额外做一些工作:总体思路是:先把这些WCF服务的程序集打包,然后利用反射加载各个WCF服务的程序集,按顺序一个一个寄宿.先来看看我们需要寄宿的WCF服务: 实现步骤: ...
- Pytorch中nn.Dropout2d的作用
Pytorch中nn.Dropout2d的作用 首先,关于Dropout方法,这篇博文有详细的介绍.简单来说, 我们在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作,这样可以使模型泛化性更 ...
- vscode调试npm包技巧
官网文档:https://code.visualstudio.com/docs/nodejs/nodejs-debugging node调试方法(日志和debuuger):https://blog.r ...