• CF1059E Split the Tree(倍增)


    题意翻译

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

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

    题解

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

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

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

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

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

     1 //minamoto
     2 #include<bits/stdc++.h>
     3 #define ll long long
     4 using namespace std;
     5 const int N=100005;
     6 int head[N],Next[N],ver[N],tot;
     7 inline void add(int u,int v){
     8     ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
     9 }
    10 int pa[N][25],top[N],son[N],dep[N],ans,n,L;ll sum[N],w[N],S;
    11 inline void init(int u){
    12     for(int i=1;i<=20;++i)
    13     pa[u][i]=pa[pa[u][i-1]][i-1];
    14     int dis=L,tmp=u;
    15     for(int i=20;i>=0;--i){
    16         int fa=pa[tmp][i];
    17         if(!fa||(1<<i)>=dis) continue;
    18         if(sum[u]-sum[fa]+w[fa]>S) continue;
    19         dis-=(1<<i),top[u]=fa,tmp=fa;
    20     }
    21 }
    22 void dfs1(int u,int fa){
    23     sum[u]=sum[fa]+w[u],top[u]=u,dep[u]=dep[fa]+1,init(u);
    24     for(int i=head[u];i;i=Next[i])
    25     dfs1(ver[i],u);
    26 }
    27 void dfs2(int u){
    28     int mx=-1;
    29     for(int i=head[u];i;i=Next[i]){
    30         int v=ver[i];dfs2(v);
    31         if(son[v]==v) continue;
    32         if(mx==-1||dep[mx]>dep[son[v]]) mx=son[v];
    33     }
    34     if(mx==-1) ++ans,mx=top[u];
    35     son[u]=mx;
    36 }
    37 int main(){
    38 //    freopen("testdata.in","r",stdin);
    39     scanf("%d%d%lld",&n,&L,&S);
    40     for(int i=1;i<=n;++i){
    41         scanf("%lld",&w[i]);
    42         if(w[i]>S) return puts("-1"),0;
    43     }
    44     for(int i=2,f;i<=n;++i)
    45     scanf("%d",&f),add(f,i),pa[i][0]=f;
    46     dfs1(1,0),dfs2(1);
    47     printf("%d
    ",ans);
    48     return 0;
    49 }
  • 相关阅读:
    Redis数据模型
    Redis集群使用的一些命令(持续更新)
    Redis简单集群搭建
    观察者模式
    抽象工厂模式
    简单工厂模式及其简单Java案例代码实现
    工厂方法模式及简单Java案例代码实现
    Java中的双重检查锁(double checked locking)
    BayaiM__MYSQL千万级数据量的优化方法积累__初级菜鸟
    BayaiM__Linux安装MySQL的两种方法
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9761742.html
Copyright © 2020-2023  润新知