zoukankan      html  css  js  c++  java
  • hdu 3290 The magic apple tree

    题目大意:给出一个有N(0<N<=20000)个节点的苹果树,这个树只有1个root(根节点),每个节点都有1个label(编号),label从1开始一直到N。苹果树的每个节点按照如下规则生长苹果:

    1.叶子节点生长出的苹果数量等于叶子节点的label。

    2.某父亲节点有K个儿子节点,直到它的K个儿子节点都生长出苹果,父亲节点才开始生长苹果。父亲节点长出的苹果数量等于它的  所有儿子中苹果数量第(k+1)/2小的  儿子节点的苹果数量。

    求根节点生长出的苹果数量。

    举个栗子:如下图所示,label为4,5,6,7的节点是叶节点,根据规则一,叶节点生长的苹果数量为他们的编号,那么他们生长出的苹果数量分别为4,5,6,7个。接下来,节点2,3的所有子节点有已经生长出苹果了,根据规则二,轮到节点2,3生长苹果了。节点2有2个子节点,根据计算:(2+1)/2 = 1,节点2的苹果数量等于它的所有儿子节点苹果数量中第1小的儿子节点苹果数量,也就是等于节点4的苹果数量。同样的,节点3的苹果数量为6。最后计算节点1的苹果数量即可。

    1、用邻接表来存储这颗树。

    2、用visit数组记录每个节点的入度,也就是方面后面找到根节点,根节点的入度为0。

    3、根据题目规则,设计DFS搜索来求每个节点的苹果数量。

    4、用优先队列来维护第(K+1)/2小的子节点苹果数量。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <queue>
     5 #include<functional>
     6 #include<vector>
     7 using namespace std;
     8 
     9 const int N = 20010;
    10 
    11 /** 子节点结构 **/
    12 typedef struct LeafNode
    13 {
    14     int label;   ///节点标号
    15     int next;    ///下个子节点地址
    16 }LeafNode;
    17 
    18 /** 父节点结构 **/
    19 typedef struct Node
    20 {
    21     int label;   ///节点标号
    22     int smaller; ///记录第几小的儿子
    23     int next;    ///儿子节点地址
    24 }Node;
    25 
    26 Node tree[N];    ///邻接表存储苹果树
    27 int visit[N];    ///记录节点的入度
    28 LeafNode leaf[N];///静态数组存储叶节点
    29 int leafIndex;   ///记录静态数组下一个可以分配的地址
    30 int n;           ///节点数量
    31 
    32 /** dfs搜索root节点的苹果数量 **/
    33 int dfs( int root )
    34 {
    35     ///root节点为叶节点,直接返回苹果数量,即label
    36     if ( -1 == tree[root].next )
    37         return tree[root].label;
    38 
    39     ///root节点为父节点,计算该节点所有子节点的苹果数量,然后在返回
    40     int p = tree[root].next;
    41     priority_queue<int,vector<int>,less<int> > Q;   ///用优先队列去维护第(k+1)/2小的子节点苹果数量
    42 
    43     while ( -1 != p )
    44     {
    45         Q.push(  dfs( leaf[p].label ) );
    46         while ( int(Q.size()) > tree[root].smaller )///优先队列中元素的数量超过(k+1)/2,表示队首放的不是我们需要的结果
    47             Q.pop();
    48         p = leaf[p].next;
    49     }
    50 
    51     return Q.top();///优先队列队首放的就是结果
    52 }
    53 
    54 /** 初始化函数 **/
    55 void init(void)
    56 {
    57     leafIndex = 0;
    58     memset(visit, 0, sizeof(visit));
    59 }
    60 
    61 /** 把编号为label的子节点添加到编号为i的父节点的邻接表上 **/
    62 void addNode( int label, int i )
    63 {
    64     visit[label]++;
    65     int tmp = leafIndex++;
    66     leaf[tmp].label = label;
    67     leaf[tmp].next = tree[i].next;
    68     tree[i].next = tmp;
    69 }
    70 
    71 int main(void)
    72 {
    73     int i,j, label;
    74     while ( scanf("%d", &n) != EOF ) ///n个节点
    75     {
    76         init();
    77         for (i = 1; i <= n; ++i)
    78         {
    79             scanf("%d", &j);
    80             tree[i].label = i;       ///初始化节点i
    81             tree[i].smaller = (j+1)/2;
    82             tree[i].next = -1;
    83             while (j--)              ///接受i节点的j个孩子
    84             {
    85                 scanf("%d", &label);
    86                 addNode(label, i);
    87             }
    88         }
    89         for ( i = 1; i <= n; ++i )
    90         {
    91             if ( 0 == visit[i] )     ///入度为0的节点为根节点,从根节点开始搜索
    92             {
    93                 printf("%d
    ",dfs(i));
    94                 break;
    95             }
    96         }
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    Ubuntu 配置IP地址方法
    ubuntu server 16.04安装GPU服务器
    Ubuntu 自动获取ip地址
    Typedef 用法
    linux mount命令详解(iso文件挂载)
    specrate 与specspeed 的区别
    SPEC CPU 使用简介
    编译错误you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this check)
    SPEC CPU 2006编译perl 出错:undefined reference to `pow'
    'gets' undeclared here (not in a function)
  • 原文地址:https://www.cnblogs.com/yongqiang/p/5644676.html
Copyright © 2011-2022 走看看