原题目: 1090 Highest Price in Supply Chain (25 分).
题意
在树根处货物的价格为P,然后每往下走一层,价格增加r%。
→ 给出供应商成员数N,价格P,增加率r,然后给出N个ID,第i个ID是第i个成员(其实是经销商)的供应商的ID。其中,若ID为-1则该成员i是根供应商。
① 求所有叶子结点中的最高价格,
② 以及这个价格的叶子结点个数,精确至2位小数。
分析
- 分析题目:拿到题目第一反应是存储结点的父结点,但是这种方法需要从叶结点向根结点遍历,会把所有路径都走一遍,且有很多重复路径,故会导致超时,没有从根结点向下遍历快;事实上,也很容易用孩子表示法。
- 确定孩子表示法,则用push_back将数组vector扩展成二维数组。
- 用DFS从根结点开始递归——更新最深层次,并记录最深层次结点数。
知识点
- 树的孩子表示法——用vector数组的push_back。
- 用DFS从根结点开始递归,获得最深层次及其结点数。
CODE
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int n, maxdepth = 0, maxnum = 0;
int tmp, root;
vector<int> v[100010];
void DFS(int root, int depth);
int main()
{
double p, r; //注意r还需要除以100
cin >> n >> p >> r;
for ( int i=0; i<n; i++ ){
cin >> tmp;
if ( tmp==-1 )
root = i; //根供应商
else
v[tmp].push_back(i); //记录供应商tmp的经销商ID(保存孩子结点)
}
//找最深层次及其结点数
DFS(root, 1);
//计算结果
double maxprice = p * pow(1+r/100, maxdepth-1); //这里注意增加的倍数是深度-1
printf("%.2f %d", maxprice, maxnum);
return 0;
}
void DFS(int root, int depth){
if ( v[root].size()==0 ){ //递归边界:叶结点
if ( maxdepth==depth ) //记录最深层次的结点数
maxnum++;
if ( maxdepth<depth ){ //出现更深的层次,则重新记录结点数
maxdepth = depth;
maxnum = 1;
}
return;
}
for ( int i=0; i<v[root].size(); i++ )
DFS(v[root][i], depth+1); //深度优先遍历每个结点的孩子结点
}
注意点
关于计算:① 题目中r给出的是百分比,计算时需要除以100;② 加一层乘一次r%,故最后一共乘(最大深度-1)次r%。