问题描述
可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记
下了他认为的各个地点的小偷数量。
现在我们将 Bibi 的家附近的地形抽象成一棵有根树。 每个地点都是树上的
一个节点,节点上都标注了 Bibi 心中该地点的小偷数量。现在 Bibi 告诉你一个
节点 k,请你求出以该节点为根的子树中小偷数量的总和,以及子树中小偷最多
的节点的小偷数量。
★数据输入
输入第一行为一个正整数 n(1≤n≤100000) 表示树的节点数目,树根的编号
总是为 1,且没有小偷。
接下来 n-1 行, 每行两个正整数 p, x(1≤x≤100)。 代表编号为 i 的节点的父
亲节点 p 和该节点的小偷数量 x。 数据保证输入的 p 小于当前的 i。 这里的 i 从 2
依次数到 n。
第 n+1 行一个整数 m(1≤m≤n), 表示询问组数。
第 n+2 行有 m 个整数,每个整数 ki(1≤ki≤n) 代表该组询问中的节点 k。
★数据输出
输出 m 行, 每行两个整数,代表以询问节点为根的子树中小偷数量的总和,
以及子树中小偷最多的节点的小偷数量。
输入示例 | 输出示例 |
3 1 56 1 82 1 1 | 138 82 |
思路
(1)这题可以用数来暴力做,用vector<>来存子节点的位置。
因为vector每次满都在开双倍空间,可能会占用较多空间,在移动数据上也会消耗更多时间
理论上因该是可行的,但是不知道是OJ使用vc6的原因还是vector开了过大空间,测试时有一个点RE
(2)用结构体数组,存好数据够从右向左遍历,将值加到对应父节点上
code
(1)使用vector,一个RE(不知道怎么死的)
#include <stdio.h> #include <stdlib.h> #include <iostream> using namespace std; #include <vector> struct Node { Node():num(0),ans_sum(0),ans_max(0){} int num; int ans_sum; int ans_max; vector<int> child; }; Node *arr = NULL; int dfs(int index) // return sum of children { arr[index].ans_sum = arr[index].num; arr[index].ans_max = arr[index].num; if(arr[index].child.empty()) { } else { int i,tmp; for(i=0;i<arr[index].child.size();i++) { arr[index].ans_sum += dfs(arr[index].child[i]); tmp = arr[arr[index].child[i]].ans_max; if(tmp>arr[index].ans_max) arr[index].ans_max = tmp; } } return arr[index].ans_sum; } int main() { int i,j; int n,p,x,m,k; scanf("%d",&n); arr = new Node[n+1];//should not use malloc for(i=2;i<=n;i++) { scanf("%d %d",&p,&x); arr[p].child.push_back(i); arr[i].num = x; } dfs(1); scanf("%d",&m); for(i=1;i<=m;i++) { scanf("%d",&k); printf("%d %d\n",arr[k].ans_sum,arr[k].ans_max); } delete[] arr; return 0; }
(2)使用结构体数组,AC
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Node { int sum; int max; int fa;//father }; int main() { int n; scanf("%d",&n); Node *p = (Node *)malloc(sizeof(Node)*(n+1)); memset(p,0,sizeof(Node)*(n+1)); //----------------------------------------------- int i,j,index; for(i=2;i<=n;i++) { scanf("%d %d",&p[i].fa,&p[i].sum); p[i].max = p[i].sum; } for(i=n;i>1;i--) { p[p[i].fa].sum+=p[i].sum; p[p[i].fa].max = p[i].max > p[p[i].fa].max ? p[i].max : p[p[i].fa].max; } scanf("%d",&j); for(i=1;i<=j;i++) { scanf("%d",&index); printf("%d %d\n",p[index].sum,p[index].max); } //----------------------------------------------- free(p); return 0; }