本题的修改过程中,解决了困扰我许久的段错误问题,纠正了一个不良变成习惯,故记录之。
题目:
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone involved in moving a product from supplier to customer.
Starting from one root supplier, everyone on the chain buys products from one's supplier in a price P and sell or distribute them in a price that is r% higher than P. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.
Now given a supply chain, you are supposed to tell the highest price we can expect from some retailers.
Input Specification:
Each input file contains one test case. For each case, The first line contains three positive numbers: N (<=105), the total number of the members in the supply chain (and hence they are numbered from 0 to N-1); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then the next line contains N numbers, each number Si is the index of the supplier for the i-th member. Sroot for the root supplier is defined to be -1. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the highest price we can expect from some retailers, accurate up to 2 decimal places, and the number of retailers that sell at the highest price. There must be one space between the two numbers. It is guaranteed that the price will not exceed 1010.
Sample Input:
9 1.80 1.00
1 5 4 4 -1 4 5 3 6
Sample Output:
1.85 2
题意:
供应商、经销商和零售商构成一棵树,每下一层,价格就会成比率增长一次,问零售商中最高价是多少(即求深度),有几个最高价。
分析:
本题考查树的dfs或bfs求深度,难点或易错点在于:
1、树的存储和结点的结构。
2、如何读取数据(题目给出的是每个节点的父结点)。
3、如何求深度。
读取数据只需要读取父结点编号,然后增加其子节点数组即可,深度及dfs或bfs,子节点入队时深度+1即可。
易错点:
对于第一个问题,牵涉到我常犯的段错误,由于考研过程中教材用的太杂,所以编程习惯比较差,不知道看了哪本书之后,习惯使用结构体指针数组保存树,而段错误其本质是使用了不该使用的空间,故而使用结构体指针数组若没有事先开辟空间,就会报错段错误,但官网给出的段错误是数组溢出或堆栈溢出,所以以前一直没有解决这个问题。
因此,解决的办法是用结构体数组,而对于某些需要用指针数组的情况(如需要根据序列创建二叉树),必须用new函数开辟空间
代码:
#include <vector>
#include <iostream>
#include <math.h>
using namespace std;
struct node{
int depth;
vector <int> child;
};
vector <node> tree;
void dfs(int root){
if(tree[root].child.size() == 0) return;
for(int i = 0;i < tree[root].child.size();i++){
tree[tree[root].child[i]].depth = tree[root].depth + 1;
dfs(tree[root].child[i]);
}
}
int n;
int main(){
double p,r;
int root;
scanf("%d %lf %lf",&n,&p,&r);
r /= 100;
tree.resize(n);
for(int i = 0;i < n;i++){
int index;
scanf("%d",&index);
if(index == -1){
root = i;
}else{
tree[index].child.push_back(i);
}
}
tree[root].depth = 0;
dfs(root);
int maxdepth = -1,maxnum = 0;
for(int i = 0;i < n;i++){
if(tree[i].depth > maxdepth){
maxdepth = tree[i].depth;
}
}
for(int i = 0;i < n;i++){
if(tree[i].depth == maxdepth)
maxnum++;
}
printf("%.2f %d",pow(1 + r,maxdepth) * p,maxnum);
return 0;
}
总结:
树的遍历题型套路固定,使用静态存储和dfs(bfs)即可。需要注意的是以后的编程中,使用指针要谨慎,事先开辟空间,防止野指针的出现。