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 树链思想的更多相关文章

  1. HDU 5242 树链剖分思想的贪心

    题意及博客 树链剖分分为2步,第一次求出深度,重儿子,第二次求出重链,用到了启发式的思想,即对于比较重的儿子,尽量去完整的维护它.类似于我们去合并两个堆,明显把小的堆逐个插入大的堆中会比大的往小的插更 ...

  2. hdu 5893 (树链剖分+合并)

    List wants to travel Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/O ...

  3. hdu 5052 树链剖分

    Yaoge’s maximum profit Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. hdu 4897 树链剖分(重轻链)

    Little Devil I Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  5. hdu 5274 树链剖分

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  6. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  7. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  8. HDU 3966 /// 树链剖分+树状数组

    题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...

  9. hdu 4729 树链剖分

    思路:这个树链剖分其实还是比较明显的.将边按权值排序后插入线段树,然后用线段树查找区间中比某个数小的数和,以及这样的数的个数.当A<=B时,就全部建新的管子. 对于A>B的情况比较 建一条 ...

随机推荐

  1. 201709-3 JSON查询

    问题描述 JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,可以用来描述半结构化的数据.JSON 格式中的基本单元是值 (value),出于简化的目的本题 ...

  2. MyBatis学习存档(2)——核心配置文件

    一.xml节点结构 configuration为根节点 properties 可以配置在Java 属性配置文件中 settings 修改 MyBatis 在运行时的行为方式 typeAliases 为 ...

  3. mybatis 延迟加载学习

    一.什么是延迟加载 resultMap可实现高级映射(使用association.collection实现一对一及一对多映射),association.collection具备延迟加载功能. 需求: ...

  4. windows安装npm教程

    1.在使用之前,先类掌握3个东西,明白它们是用来干什么的: npm:  nodejs 下的包管理器. webpack: 它主要用途是通过CommonJS 的语法把所有浏览器端需要发布的静态资源作相应的 ...

  5. ubuntu 网卡名称重命名

    ubuntu 网卡名称重命名 参考:https://blog.csdn.net/hzj_001/article/details/81587824 biosdevname 和 net.ifnames 两 ...

  6. Yali7月集训Contest2 T1 Cube 题解

    题目链接: 连我们都只有纸质题目...话说雅礼集训都是这样的吗... 大意 0维基本图形是一个点 1维基本图形是一条线段 2维基本图形是一个正方形 3维基本图形是一个正方体 4维基本图形是... 求\ ...

  7. SQL中 left join 的底层原理

    介绍 left join的实现效果就是保留左表的全部信息,将右表往左表上拼接,如果拼不上则为NULL. 除了left join以外,还有inner join.outer join.right join ...

  8. 如何使用koa搭建一个简单服务

    1.首先检测是否已经有node环境?   把Windows的黑窗体的命令行工具调用出来   敲击命令行node -v , 然后,就可以看到这个打印出了一个版本号,这就证明我们的node.js已经是安装 ...

  9. 第二卷 第一章 伪IOC容器--羊墅

    写在前面: Spring自诞生起,就被人称作“万能胶”,核心服务就是解耦 ,随着Spring5的出现,已经形成一个生态,被人称作spring全家桶,而且逐步在去serlvet化,去tomcat化,大有 ...

  10. Python lambda 知识点

    作者说学会了lambda后,你会用上瘾的,因为让代码复用和简洁. 初识lamdba不太好理解,尤其是它能当着一个变量传递给函数,不过多学着写几个例子就好了,下面是我的学习笔记. lambda 操作符( ...