poj1694

 1 /*给出一棵树的描述
 2 第一行输入t,代表案例的个数
 3 第二行一个n代表这棵树有n个节点
 4 接下来n行第一个数是节点的编号,根节点编号为1,然后第二个数是节点的个数,如果为0那就没子节点,否则输入节点的
 5 编号
 6 方法:递归+排序
 7 先求出根节点的r个子节点需要的最小石头数,然后按大到小排序r1,r2,r3..rr,另结果result初值为最大的那个
 8 r1,然后剩下为remain=result-1,然后将remain从r2遍历到rr,如果都比remainxiao说明剩下的可以满足,否则结果
 9 result+=ri-remain,remain=ri-1;,遍历r个数以后就可以得出结果
10 上面过程可以用递归实现
11 */
12 
13 #include <stdio.h>
14 #include <iostream>
15 #include <string.h>
16 #include <string>
17 #include <algorithm>
18 #include <vector>
19 using namespace std;
20 #define MAX 250
21 struct point
22 {
23     int num;//该节点的标号
24     vector<int> chind;//存储孩子的标号
25     int allchild;//存储孩子的个数
26 };
27 int cacl(int root,point *T)
28 {
29     int i;
30     vector<int> v;
31     if(T[root].allchild==0) return 1;
32     else
33     {
34         for(i=0;i<T[root].allchild;i++)
35           v.push_back(cacl(T[root].chind[i]-1,T) );//T[root].chind[i]-1比表示孩子的在这个容器中的编号
36         sort(v.begin(),v.end());
37         int result=v.back();
38         int  remain=result-1;//该节点要放一个
39         for(i=T[root].allchild-2;i>=0;i--)
40         {
41             if(remain>=v[i]) remain--;
42             else
43             {
44                 result=result+v[i]-remain;
45                 remain=v[i]-1;
46             }
47         }
48          return result;
49     }
50 }
51 int main()
52 {
53     int i,j,n,k;
54     int t;
55     scanf("%d",&t);
56 
57     while(t--)
58     {
59         point *T=new point[MAX];//定义一个结构体指针,指向结构体数组
60         scanf("%d",&n);
61         k=0;
62         while(n--)
63         {
64             scanf("%d",&T[k].num);
65             scanf("%d",&T[k].allchild);
66             for(i=0;i<T[k].allchild;i++)
67             {
68                 scanf("%d",&j);
69                 T[k].chind.push_back(j);
70             }
71             k++;
72         }
73         int sum=cacl(0,T);
74         printf("%d
",sum);
75         delete T;
76     }
77     return 0;
78 }

18:07:2418:07:2518:07:26

原文地址:https://www.cnblogs.com/okboy/p/3223437.html