zoukankan      html  css  js  c++  java
  • D

      这道题其实很简单,求k个到根的链,使得链上的节点的个数尽可能多,如果节点被计算过了,就不能再被计算了,其实我们发现,只要k>=叶子节点,那么肯定是全部,所以我们考虑所有的叶子节点,DFS到根节点后,往上递归,我们能比较容易的求出某个节点,所有儿子节点的最深深度,那么对于上面一个节点,其实只有一个最长那个影响,所有我们可以保存每个节点的最深深度,然后往上递归,递归到某个节点的时候,查询所有子树的最深深度,把这个最深深度+1当场当前节点的最深深度,其他节点实际上已经变成链了,那么我们用优先队列保存所有的链,也就是对应链的长度,然后找出前k大的链,求和即可,这样就不会重复了。

      

    #include<bits/stdc++.h>
    using namespace std;
    const int maxx = 2e5+6;
    int ver[maxx],edge[maxx],head[maxx],Next[maxx];
    int n,k,tot;
    priority_queue<int>q;
    int d[maxx];
    void add(int x,int y){
       ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
       ver[++tot]=x;Next[tot]=head[y];head[y]=tot;
    }
    int dfs(int u,int fa){
       d[u]=1;
       priority_queue<int>s;
       s.push(d[u]);
       for (int i=head[u];i;i=Next[i]){
          int v=ver[i];
          if (v==fa)continue;
          dfs(v,u);
          s.push(d[v]+1);
       }
       d[u]=s.top();
       s.pop();
       while(s.size()){
          q.push(s.top()-1);
          s.pop();
       }
    }
    int main(){
       while(~scanf("%d%d",&n,&k)){
          for (int i=2;i<=n;i++){
            int tmp;
            scanf("%d",&tmp);
            add(i,tmp);
          }
          dfs(1,0);
          q.push(d[1]);
          int sz=q.size();
          int ans=0;
          for (int i=1;i<=min(sz,k);i++){
            ans+=q.top();
            q.pop();
          }
          printf("%d
    ",ans);
       }
       return 0;
    }
  • 相关阅读:
    Linux命令备忘录
    Redis集群部署
    Java BIO、NIO、AIO 学习
    elasticsearch性能因素总结
    tomcat配置文件server.xml详解
    Tomcat性能优化及JVM内存工作原理
    JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
    HttpClient使用学习
    Java的三种代理模式
    yzoi1109&&viojs1042最小步数的一点看法——回文数
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11634284.html
Copyright © 2011-2022 走看看