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