bzoj3011 [Usaco2012 Dec]Running Away From the Barn (可并堆)
来源:互联网 发布:淘宝退货申请假冒品牌 编辑:程序博客网 时间:2024/06/04 00:46
Description
It’s milking time at Farmer John’s farm, but the cows have all run away! Farmer John needs to round them all up, and needs your help in the search. FJ’s farm is a series of N (1 <= N <= 200,000) pastures numbered 1…N connected by N - 1 bidirectional paths. The barn is located at pasture 1, and it is possible to reach any pasture from the barn. FJ’s cows were in their pastures this morning, but who knows where they ran to by now. FJ does know that the cows only run away from the barn, and they are too lazy to run a distance of more than L. For every pasture, FJ wants to know how many different pastures cows starting in that pasture could have ended up in. Note: 64-bit integers (int64 in Pascal, long long in C/C++ and long in Java) are needed to store the distance values.
Input
* Line 1: 2 integers, N and L (1 <= N <= 200,000, 1 <= L <= 10^18)
* Lines 2..N: The ith line contains two integers p_i and l_i. p_i (1 <= p_i < i) is the first pasture on the shortest path between pasture i and the barn, and l_i (1 <= l_i <= 10^12) is the length of that path.
Output
* Lines 1..N: One number per line, the number on line i is the number pastures that can be reached from pasture i by taking roads that lead strictly farther away from the barn (pasture 1) whose total length does not exceed L.
Sample Input
1 4
2 3
1 5
Sample Output
2
1
1
OUTPUT DETAILS: Cows from pasture 1 can hide at pastures 1, 2, and 4. Cows from pasture 2 can hide at pastures 2 and 3. Pasture 3 and 4 are as far from the barn as possible, and the cows can hide there.
HINT
Source
分析:
果然可并堆的题目隐藏的都很深,不是每道题都像罗马游戏那样让你练板子的
受到这道题的启发
这道题乍看上去和可并堆没有什么关系,
题目有一个很奇特的限制:计算子树内到达根结点距离不超过L的结点个数
因为是路劲一端一定是根结点,所以我们可以simple的用两个结点深度相减得到距离
同时,这提示我们可以dfs维护子树信息
假设我们已经知道x这棵子树中满足条件的结点数,
向上回溯的时候,我们需要把儿子的信息都合并到父亲上
但是这样就会出现一些不符合条件的结点
我们就需要查找出这些结点并且删除ta们
这些要被删除的结点有一个显而易见的性质:ta们的深度一定很大
所以我们可以把结点按照dis从大到小判断
这样来看,我们需要一种数据结构,支持:快速查找最大值,删除,合并
可并堆
tip
题目中描述有误,应为“小于等于l”
我发现网上的代码中
对于根结点的查找,有的用的是并查集,有的直接用一个数组
我仔细的观察了一下:
如果是题目给出的是集合的形式,那么多半使用并查集查询根结点
如果题目本身就是一种树形结构,这样在dfs并且合并的时候,在一定程度上是有序的,所以可以用一个数组完成根结点的维护
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#define ll long longusing namespace std;const int N=200010;int n,ch[N][2],root[N],dis[N],sz[N];ll val[N],m; struct node{ int x,y,nxt; ll v;};node way[N<<1];int st[N],tot=0;void add(int u,int w,ll z){ tot++; way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].nxt=st[u];st[u]=tot;}int merge(int x,int y){ if (!x) return y; if (!y) return x; if (val[x]<val[y]) swap(x,y); ch[x][1]=merge(ch[x][1],y); if (dis[ch[x][0]]<dis[ch[x][1]]) swap(ch[x][0],ch[x][1]); if (!ch[x][1]) dis[x]=0; else dis[x]=dis[ch[x][1]]+1; return x;}void dfs(int now){ sz[now]=1,root[now]=now; for (int i=st[now];i;i=way[i].nxt) { val[way[i].y]=val[now]+way[i].v; //深度 dfs(way[i].y); sz[now]+=sz[way[i].y]; root[now]=root[way[i].y]=merge(root[now],root[way[i].y]); } while (val[root[now]]-val[now]>m) { sz[now]--; root[now]=merge(ch[root[now]][0],ch[root[now]][1]); }}int main(){ scanf("%d%lld",&n,&m); for (int i=2;i<=n;i++) { int x; ll z; scanf("%d%lld",&x,&z); add(x,i,z); } dfs(1); for (int i=1;i<=n;i++) printf("%d\n",sz[i]); return 0;}
- [BZOJ3011][Usaco2012 Dec]Running Away From the Barn(可并堆)
- bzoj3011 [Usaco2012 Dec]Running Away From the Barn (可并堆)
- 【BZOJ3011】[Usaco2012 Dec]Running Away From the Barn【可并堆】
- BZOJ3011: [Usaco2012 Dec]Running Away From the Barn 可并堆
- bzoj3011: [Usaco2012 Dec]Running Away From the Barn 可并堆(左偏树)
- bzoj 3011: [Usaco2012 Dec]Running Away From the Barn (可并堆)
- 【bzoj3011】[Usaco2012 Dec]Running Away From the Barn
- BZOJ 3011 Usaco2012 Dec Running Away From the Barn 可并堆
- [可并堆] BZOJ 3011 [Usaco2012 Dec]Running Away From the Barn
- 【BZOJ 3011】[Usaco2012 Dec]Running Away From the Barn 可并堆
- 3011: [Usaco2012 Dec]Running Away From the Barn
- bzoj-3011 Running Away From the Barn
- 【bzoj3012】[Usaco2012 Dec]First(题解)
- bzoj3012 [Usaco2012 Dec]First!
- 【bzoj3012】[Usaco2012 Dec]First!
- 左偏树(可并堆)
- Securing the Barn(dfs)
- please take me away from the world
- JS修改成功跳出弹窗,返回到上一页面
- vba 个人使用总结笔记
- 基于MATLAB的LDL分解法
- 使用Android-skin-support生成换肤包
- 安卓之路问题三
- bzoj3011 [Usaco2012 Dec]Running Away From the Barn (可并堆)
- 无人机系统PX4视频教程:飞行PID参数调试
- 菜鸟日记(yzy) 微信公众号网页的开发-websocket
- 生成HFile以及入库到HBase
- windows任务计划
- centos7中yum安装软件问题
- Windows线程启动和消亡详解
- Storm Trident API 使用详解
- java io File API的使用