• 想象一下(imagine)


    想象一下(imagine)

    题目描述

     

    我们高大的老班举起了有半个他那么高的三角板,说:“你们想象一下——”

    于是你就陷入了想象……

    有一棵n个点的树,每个叶子节点上都有一个人,他们按照每秒钟走一条边的速度向树根(节点1)前进。

    你可以运用k次想象之力,让某一个节点(除了根节点)上的所有人瞬间(耗时为0)转移到这个节点的父亲上。

    你想知道最少需要多少时间,所有人可以到达根节点。

     

    输入

     

    输入的第一行包含两个整数n,k,含义见问题描述。

    接下来n-1行,第i行一个整数fai,表示节点i的父亲为fai。

     

    输出

     

    输出一行一个整数,表示所有人到达根节点最少需要的时间。

     

    样例输入

    <span style="color:#333333"><span style="color:#333333">【样例1输入】
    6 2
    1
    2
    2
    2
    4
    【样例2输入】
    3 2
    1
    2
    
    </span></span>

    样例输出

    <span style="color:#333333"><span style="color:#333333">【样例1输出】
    1
    【样例2输出】
    0</span></span>

    提示

     

     

     

    【样例1说明】

    一开始,在节点3,5,6上分别有一个人,我们称他们为A,B,C。

    时刻0,在节点6运用想象之力,A到达节点4。

    第1秒,A,B,C走到节点2。

    时刻1,在节点2运用想象之力,A,B,C到达节点1,即目的地。

    共用时1秒。

     

    【样例2说明】

    一开始只有节点3上有一个人。

    时刻0,在节点3运用想象之力,这个人到达节点2;

    此时仍然为时刻0,在节点2运用想象之力,这个人到达节点1。

    【子任务】

    测试点

    n

    k

    特殊性质

    1

    ≤8

    <n

    2~4

    ≤100

    5~8

    ≤3000

    9

    ≤500000

    =1

    10

    <n

    树是一条链

    11~20

     


    solution

    考场时的想法:答案是有单调性的,那我二分一个mid,然后把所有点往上跳mid步

    在用树形dp看看是否合法

    效率O(nlog2) 90分

    然而这题有O(n)做法

    贪心把所有叶子往上跳,如果剩下的边不足k条,就break

    因为想象应该越晚用越好(一次拉多个)

    好吧说实话我也不太会证

    1.一个节点最多只会使用1次想象之力(当最后一个人经过它的时候)
    2.对于一个人来说,对他用的想象之力一定越靠近根越好(尽可能多的与其它点共用)。
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define maxn 500005
    using namespace std;
    int n,K,f[maxn],flag[maxn],s[maxn],ans;
    struct node{
        int x,bs;
    };
    queue<node>q;
    int main(){
        cin>>n>>K;
        for(int i=2;i<=n;i++){
            scanf("%d",&f[i]);
            s[f[i]]++;
        }
        for(int i=1;i<=n;i++)if(!s[i])q.push(node{i,0});
        int sum=n-1;if(K==sum){puts("0");return 0;}
        while(!q.empty()){
            node a=q.front();q.pop();
            sum--;if(sum<=K){ans=a.bs+1;break;}
            s[f[a.x]]--;
            if(!s[f[a.x]]){
                node ne;ne.x=f[a.x];ne.bs=a.bs+1;
                q.push(ne);
            }
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    mysql 视图使用
    mysql 5.7 Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ...报错
    mysql创建数据库指定字符集和校对规则
    grep 命令使用
    awk 命令使用
    if [ $# -ne 1 ] 作用
    shell 获取当前目录下的jar文件
    jar 命令使用
    unzip 命令指定解压路径
    Win10系列:JavaScript写入和读取文件
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358805.html
Copyright © 2020-2023  润新知