1079. Total Sales of Supply Chain (25) -记录层的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 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 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



题目要求根据某商品的供应链条,求零售商的销售额之和,零售商的售价不同在于每一级都有涨幅,这个问题的本质就是BFS,对不同层的零售商按照所在层求销售额,然后全部加和。

因为只有叶子结点才是零售商,因此不能额外统计非零售商的情况,我们不区分叶子结点,而是让所有非叶子结点的销售量为0,这样就可以统一问题,计数全部结点了。

本题目中的图是一棵树,因此不必用visited来记录结点访问情况,因为不会出现重复访问的情况。

要记录层,定义变量tail和last,tail代表下一层的尾巴,last代表本层的尾巴,首先让last和tail都初始化为源点,接着在邻接点遍历时一直用tail记录该邻接点,当last和当前出队结点v一致时,说明这一层结束,这时候last指向的恰是这一层最后一个元素的最后一个邻接点,也就是下一层的尾巴,因此这时候让last=tail,就可以按照同样的逻辑进行下一层。

在每次换层时注意对价格的处理,对每个出队结点计算销售额,加和即可。

代码如下:

#include <iostream>
#include <vector>
#include <stdio.h>
#include <queue>

using namespace std;

int main()
{
    int N;
    double rootPrice,percent;
    cin >> N >> rootPrice >> percent;
    vector<vector<int> > graph(N);
    vector<int> nodeSales(N);
    for(int i = 0; i < N; i++){
        int cnt,num;
        scanf("%d",&cnt);
        if(cnt == 0){
            scanf("%d",&num);
            nodeSales[i] = num;
            graph[i].clear();
            continue;
        }else{
            nodeSales[i] = 0;
        }
        for(int j = 0; j < cnt; j++){
            scanf("%d",&num);
            graph[i].push_back(num);
        }
    }
    queue<int> q;
    q.push(0);
    double sum = 0;
    double factor = rootPrice;
    int tail = 0;
    int last = 0;
    while(!q.empty()){

        int v = q.front();
        q.pop();

        sum += nodeSales[v] * factor;

        for(int i = 0; i < graph[v].size(); i++){
            int w = graph[v][i];
            q.push(w);
            tail = w;
        }

        if(v == last){
            factor *= (1 + percent / 100);
            last = tail;
        }

    }

    printf("%.1lf\n",sum);

    return 0;
}


posted on 2015-08-23 22:57  张大大123  阅读(168)  评论(0编辑  收藏  举报

导航