PAT Advanced 1079 Total Sales of Supply Chain (25) [DFS,BFS,树的遍历]

题目

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. Only the retailers will face the customers. 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 total sales from all the 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 their ID’s are numbered from 0 to N-1, and the root supplier’s ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then N lines follow, each describes a distributor or retailer in the following format:

Ki ID[1] ID[2] … ID[Ki]

where in the i-th line, Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID’s of these distributors or retailers. Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given afer Kj. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place. It is guaranteed that the number will not exceed 1010.

Sample Input:

10 1.80 1.00

3 2 3 5

1 9

1 4

1 7

0 7

2 6 1

1 8

0 9

0 4

0 3

Sample Output:

42.4

题目分析

供应商,经销商,零售商组成一棵树,每条销售渠道对应树的一条从根节点到叶结点的路径,已知每条渠道商品数,原价格,每个经销商和零售商价格增率,求总销售额

翻译:已知每个节点子节点数,及根节点到每一个子节点路径上的商品数,商品的原价p,每一个代理商品价格倍增率r%,求销售总金额

解题思路

思路 01(DFS 最优)

  1. 邻接表表示树,int cns[n]记录节点子节点数,max_h记录最大层数
  2. dfs深度优先遍历,遇到叶子节点(当前节点子节点数为0)计算当前路径销售金额,dfs函数参数price记录当前层价格

思路 02(BFS)

  1. 邻接表表示树,int cns[n]记录节点子节点数,max_h记录最大层数,int h[n]记录节点所在层数,int pro[n]记录对应层的叶子节点数
  2. bfs广度优先遍历,遇到叶子节点(当前节点子节点数为0)记录当前路径的产品数到对应层pro[h[index]]中
  3. 遍历每一层叶子结点数,统计当前层销售价,并求出总销售价

知识点

  1. bfs使用int h[n]数组记录节点的层数
  2. dfs函数参数h记录当前处理节点的层数

Code

Code 01(DFS 最优)

#include <iostream>
#include <vector>
using namespace std;
const int maxn=100000;
vector<int> nds[maxn];
int cns[maxn];//记录子结点数
double p,r,sales;
void dfs(int index,double price){
if(cns[index]==0){
//retailer
sales+=nds[index][0]*price;
return;
}
for(int i=0;i<nds[index].size();i++){
dfs(nds[index][i],price*(1+r*0.01));
}
}
int main(int argc,char * argv[]){
int n,k,cid;
scanf("%d %lf %lf",&n,&p,&r);
for(int i=0;i<n;i++){
scanf("%d",&cns[i]);
int len=cns[i]==0?1:cns[i];
for(int j=0;j<len;j++){
scanf("%d",&cid);
nds[i].push_back(cid);
}
}
dfs(0,p);
printf("%.1f",sales);
}

Code 02 (DFS)

#include <iostream>
#include <vector>
using namespace std;
const int maxn = 100010;
vector<int> nds[maxn];
int pn[maxn]; //记录经销商产品数量
double r,total;
void dfs(int index, double p) {
if(nds[index].size()==0) {
total+=p*pn[index];
return;
}
for(int i=0; i<nds[index].size(); i++)
dfs(nds[index][i], p*(1+r));
}
int main(int argc,char * argv[]) {
int n,k,cid;
double p;
scanf("%d %lf %lf", &n, &p, &r);
for(int i=0; i<n; i++) {
scanf("%d", &k);
if(k==0)scanf("%d",&pn[i]);
for(int j=0; j<k; j++) {
scanf("%d", &cid);
nds[i].push_back(cid);
}
}
r=r*0.01;
dfs(0,p);
printf("%.1f",total);
return 0;
}

Code 03(BFS)

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int maxn=100000;
vector<int> nds[maxn];
int cns[maxn],pro[maxn],h[maxn],max_h;//cns记录子结点数,pro记录层叶子结点数
double p,r,sales;
void bfs(){
queue<int> q;
q.push(0);
while(!q.empty()){
int index = q.front();
q.pop();
max_h=max(max_h,h[index]);
if(cns[index]==0){
pro[h[index]]+=nds[index][0];
}else{
for(int i=0;i<nds[index].size();i++){
h[nds[index][i]]=h[index]+1;
q.push(nds[index][i]);
}
}
}
}
int main(int argc,char * argv[]){
int n,k,cid;
scanf("%d %lf %lf",&n,&p,&r);
for(int i=0;i<n;i++){
scanf("%d",&cns[i]);
int len=cns[i]==0?1:cns[i];
for(int j=0;j<len;j++){
scanf("%d",&cid);
nds[i].push_back(cid);
}
}
h[0]=0;
bfs();
for(int i=0;i<=max_h;i++){
sales+=pro[i]*p;
p*=(1+r*0.01);
}
printf("%.1f",sales);
return 0;
}
上一篇:首届.NET Core开源峰会


下一篇:PAT 甲级 1079 Total Sales of Supply Chain (25 分)(简单,不建树,bfs即可)