1079 Total Sales of Supply Chain (25 分)

1079 Total Sales of Supply Chain (25 分)
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 (≤10^5​​ ), 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:

K​i ID[1] ID[2] … ID[Ki]

where in the i-th line, K​i 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 after 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 10^10.

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。零售商作为叶子结点,给出零售商的销售量,其他结点给出它们的子结点。求出货物的价格之和

错误代码:
一开始想着用一个vector存储每个结点的子结点信息,用两个vector分别存储代表销售商的结点的id和货物数量,结果运行超时

#include<bits/stdc++.h>
using namespace std;
double sum = 0;
vector<vector<int>> nextNode;
vector<int> retailer,retailerNum;
double p, r;
int nodeNum;
void DFS(int id,int layer){
    
    
  for (int i = 0; i < retailer.size();i++){
    
    //和代表销售商的结点匹配
    if(id==retailer[i]){
    
    
      sum += p * pow(0.01 * r + 1, layer) * retailerNum[i];
      return;
    }
  }
  for (int i = 0; i < nextNode[id].size(); i++)
    {
    
    
        DFS(nextNode[id][i], layer + 1);//如果有子结点,遍历子结点
    }
}

int main(){
    
    
  cin >> nodeNum >> p >> r;
  nextNode.resize(nodeNum + 1);
  int a, b;
  for (int i = 0; i < nodeNum;i++){
    
    
    cin >> a;
    if(a==0){
    
    
      cin >> b;
      retailer.push_back(i);//存销售商结点的id
      retailerNum.push_back(b);//存销售货物
      }
    for (int j = 0; j < a;j++){
    
    
      cin >> b;
      nextNode[i].push_back(b);//存子结点信息
    }
  }
  DFS(0, 0);
  printf("%.1lf", sum);

  return 0;
}

后参考柳神的代码,用结构体存储每一个结点的孩子结点的id,如果没有孩子结点则存货物的数量。在进行DFS的时候,如果该结点有孩子结点,则继续遍历孩子结点,如果没有,则计算sum,作为递归的出口

AC代码

#include<bits/stdc++.h>
using namespace std;
double sum = 0;
struct node{
    
    
  int num;
  vector<int> nextNode;
};
vector<node> v;
double p, r;
int nodeNum;
void DFS(int id,int layer){
    
    
  if(v[id].nextNode.size()==0){
    
    //没有孩子结点就计算sum,作为递归的出口
    sum += p * pow(0.01 * r + 1, layer) * v[id].num;
  }
  else{
    
    //有孩子结点,则继续遍历
    for (int i = 0; i < v[id].nextNode.size(); i++){
    
    
        DFS(v[id].nextNode[i], layer + 1);
      }  
  }
}

int main(){
    
    
  cin >> nodeNum >> p >> r;
  v.resize(nodeNum + 1);//别少了这一步,会段错误,这句话的细节我目前还没完全弄懂
  int a, b;
  for (int i = 0; i < nodeNum;i++){
    
    
    cin >> a;
    if(a==0){
    
    
      cin >> b;
      v[i].num = b;//存货物的数量
      }
    for (int j = 0; j < a;j++){
    
    
      cin >> b;
      v[i].nextNode.push_back(b);//存子结点的信息
    }
  }
  DFS(0, 0);
  printf("%.1lf", sum);
  return 0;
}

总结:在代码的结构设计以及数据结构的选择上还需要积累经验,按照第二种做法可以去掉DFS里的一层循环,大大降低了时间复杂度

猜你喜欢

转载自blog.csdn.net/weixin_48954087/article/details/113795759