题意翻译

现有n个点组成一棵以1为根的有根树,第i个点的点权为wi,需将其分成若干条垂直路径使得每一个点当且仅当被一条垂直路径覆盖,同时,每条垂直路径长度不能超过L,点权和不能超过S,求最少需要几条垂直路径才能满足要求。特别地,无解输出-1。

一条垂直路径是一条包含v1, v2...vk的路径,使得vi(i>=2)是vi-1的父亲。

题解

话说莫不是树上的题目全都可以用倍增艹过去……

首先,这个东西是可以贪心的,我们每一次一定是选取子树里能向上拓展最多的点与自己连成一条链

然后每一个节点最多能向上拓展多少可以用倍增预处理出来

然后直接在dfs的时候判断即可

一开始也想到要贪心了……然而最后倍增那一步没想到233

 //minamoto
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=;
int head[N],Next[N],ver[N],tot;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
}
int pa[N][],top[N],son[N],dep[N],ans,n,L;ll sum[N],w[N],S;
inline void init(int u){
for(int i=;i<=;++i)
pa[u][i]=pa[pa[u][i-]][i-];
int dis=L,tmp=u;
for(int i=;i>=;--i){
int fa=pa[tmp][i];
if(!fa||(<<i)>=dis) continue;
if(sum[u]-sum[fa]+w[fa]>S) continue;
dis-=(<<i),top[u]=fa,tmp=fa;
}
}
void dfs1(int u,int fa){
sum[u]=sum[fa]+w[u],top[u]=u,dep[u]=dep[fa]+,init(u);
for(int i=head[u];i;i=Next[i])
dfs1(ver[i],u);
}
void dfs2(int u){
int mx=-;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];dfs2(v);
if(son[v]==v) continue;
if(mx==-||dep[mx]>dep[son[v]]) mx=son[v];
}
if(mx==-) ++ans,mx=top[u];
son[u]=mx;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d%lld",&n,&L,&S);
for(int i=;i<=n;++i){
scanf("%lld",&w[i]);
if(w[i]>S) return puts("-1"),;
}
for(int i=,f;i<=n;++i)
scanf("%d",&f),add(f,i),pa[i][]=f;
dfs1(,),dfs2();
printf("%d\n",ans);
return ;
}

CF1059E Split the Tree(倍增)的更多相关文章

  1. [CF1059E]Split the Tree[贪心+树上倍增]

    题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...

  2. [CodeForces1059E] Split the Tree

    树形DP. 用倍增处理出来每个点往上能延伸出去的最远路径,nlogn 对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x] #inclu ...

  3. [Split The Tree][dfs序+树状数组求区间数的种数]

    Split The Tree 时间限制: 1 Sec  内存限制: 128 MB提交: 46  解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...

  4. Split The Tree

    Split The Tree 时间限制: 1 Sec  内存限制: 128 MB 题目描述 You are given a tree with n vertices, numbered from 1 ...

  5. HDU6504 Problem E. Split The Tree【dsu on tree】

    Problem E. Split The Tree Problem Description You are given a tree with n vertices, numbered from 1 ...

  6. Codeforces Round #514 (Div. 2) E. Split the Tree(倍增+贪心)

    https://codeforces.com/contest/1059/problem/E 题意 给出一棵树,每个点都有一个权值,要求你找出最少条链,保证每个点都属于一条链,而且每条链不超过L个点 和 ...

  7. 2018 ICPC青岛网络赛 B. Red Black Tree(倍增lca好题)

    BaoBao has just found a rooted tree with n vertices and (n-1) weighted edges in his backyard. Among ...

  8. CF 208E. Blood Cousins [dsu on tree 倍增]

    题意:给出一个森林,求和一个点有相同k级祖先的点有多少 倍增求父亲然后和上题一样还不用哈希了... #include <iostream> #include <cstdio> ...

  9. Codeforces 1140G Double Tree 倍增 + dp

    刚开始, 我以为两个点肯定是通过树上最短路径过去的, 无非是在两棵树之间来回切换, 这个可以用倍增 + dp 去维护它. 但是后来又发现, 它可以不通过树上最短路径过去, 我们考虑这样一种情况, 起点 ...

随机推荐

  1. Python演绎的精彩故事(二)

    书接上回.在展示了App最顶层的代码后,我们去看看各模块怎样编程. 为了能看懂各模块的代码,首先须要铺垫一下Softchip架构的基本概念和设计规范. 1.随意模块不持有其它模块的实例.自然不再显式使 ...

  2. maven优化依赖

    maven-dependency-plugin最大的用途是帮助分析项目依赖,dependency:list能够列出项目最终解析到的依赖列表,dependency:tree能进一步的描绘项目依赖树,de ...

  3. Kubernetes实战阅读笔记--1、介绍

    1.业界根据云计算提供服务资源的类型将其划分为三大类: 基础设施即服务(Infrastructure-as-a-Service,IaaS).平台即服务(Platform-as-a-Service,Pa ...

  4. js对闭包的理解

    原文链接http://www.jb51.net/article/24101.htm,讲的很好,清晰明了.

  5. 更改scroll样式

    /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 2px; height: 80%; background: #fff; } /*定 ...

  6. 数据结构之 图论---基于邻接矩阵的广度优先搜索遍历(输出bfs遍历序列)

    数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索( ...

  7. POJ3680 Intervals —— 区间k覆盖问题(最小费用流)

    题目链接:https://vjudge.net/problem/POJ-3680 Intervals Time Limit: 5000MS   Memory Limit: 65536K Total S ...

  8. HDU1964 Pipes —— 插头DP

    题目链接:https://vjudge.net/problem/HDU-1964 Pipes Time Limit: 5000/1000 MS (Java/Others)    Memory Limi ...

  9. CentOS7 安装jdk8

    1.下载jdk8 jdk-8u162-linux-x64.tar.gz 2.解压 tar -vxf jdk-8u162-linux-x64.tar.gz 3.进入 jdk1.8.0_162 文件夹 终 ...

  10. Objective-C - - 字符串与数字互相转换

    NSString *string = @"123"; // 1.字符串转int int intString = [string intValue]; // 2.int装字符串 NS ...