【PAT甲级 - C++题解】1106 Lowest Price in Supply Chain

简介: 【PAT甲级 - C++题解】1106 Lowest Price in Supply Chain

1106 Lowest Price in Supply Chain

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 lowest price a customer can expect from some retailers.

Input Specification:


6.png

Output Specification:


For each test case, print in one line the lowest price we can expect from some retailers, accurate up to 4 decimal places, and the number of retailers that sell at the lowest price. There must be one space between the two numbers. It is guaranteed that the all the prices will not exceed 1010.

Sample Input:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0
2 6 1
1 8
0
0
0


Sample Output:

1.8362 2


题意


供应链是由零售商,经销商和供应商构成的销售网络,每个人都参与将产品从供应商转移到客户的过程。


整个销售网络可以看作一个树形结构,从根部的供应商往下,每个人从上一级供应商中买入商品后,假定买入价格为 P ,则会以高出买入价 r% 的价格向下出售。


只有零售商(即叶节点)可以直接将产品销售给顾客。


现在,给定整个销售网络,输出零售商可达到的最低销售价格,保留四位小数,以及可达到最低销售价格的零售商的数量。


第一行包含三个数,N 表示供应链总成员数(所有成员编号从 0 到 N−1 ,根部供应商编号为 0 ),P 表示根部供应商的每件产品的售卖价格,r ,溢价百分比。


接下来 N 行,每行包含一个成员的信息,格式如下:

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

其中第 i 行,Ki 表示从供应商 i 直接进货的成员数,接下来 Ki 个整数是每个进货成员的编号。

如果某一行的 Kj0 ,则表示这是零售商。



思路


我们可以用一个数组 p 来存储每个结点的父结点,并且再用一个数组 is_leaf 来判断每个结点是否是叶子结点。另外,当 k 为 0 时,代表该结点是根供应商。

通过树形 DP 来计算树的深度,用一个 f 数组来存储每次计算的值,这样就可以排除重复计算的步骤。

计算总销售额时只用判断每次遍历的结点是否为叶子结点即可,然后通过公式 P * pow(1 + R / 100, dfs(i)) 计算该叶子结点即零售商的销售额。其中,P 表示产品的单位价格,pow(1 + R / 100, dfs(i)) 则是计算 1 + R/100 的 dfs(i) 次方即每多一层关系次方数就加 1 。每次计算完之后,再去判断当前深度是否是最小值(因为价格是固定的,所以深度越小的零售商的销售额越小),如果是最小值则更新答案,如果等于最小值则最小销售额的销售商数量加 1 。

输出最终结果,注意销售额最小值保留四个小数点。

代码

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
int n;
double P, R;
int p[N], f[N];
bool is_leaf[N];
//树形DP,记忆化搜索
int dfs(int u)
{
    //剪枝,如果f[u]已经被计算过,直接返回即可
    if (f[u] != -1)    return f[u];
    //如果该结点没有父结点,直接返回0,同时更新f[u]
    if (p[u] == -1)    return f[u] = 0;
    return f[u] = dfs(p[u]) + 1;
}
int main()
{
    cin >> n >> P >> R;
    //输入结点信息
    memset(p, -1, sizeof p);
    for (int i = 0; i < n; i++)
    {
        int k;
        cin >> k;
        for (int j = 0; j < k; j++)
        {
            int son;
            cin >> son;
            p[son] = i;   //记录父结点是谁
        }
        if (!k)  is_leaf[i] = true;
    }
    memset(f, -1, sizeof f);
    //找到从根结点到叶子结点最短的深度
    int res = n, cnt = 0;
    for (int i = 0; i < n; i++)
        if (is_leaf[i])
        {
            if (dfs(i) < res)  res = dfs(i), cnt = 1;
            else if (dfs(i) == res)    cnt++;
        }
    printf("%.4lf %d\n", P * pow(1 + R / 100, res), cnt);
    return 0;
}
目录
相关文章
|
11月前
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
35 0
|
11月前
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
55 0
|
11月前
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
49 0
|
3天前
|
编译器 C++
【C++】一文全解四种经典 [ 特殊类 ]的设计
【C++】一文全解四种经典 [ 特殊类 ]的设计
|
4天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-3
c++初阶------类和对象(六大默认构造函数的揭破)
|
4天前
|
编译器 C语言 C++
c++初阶------类和对象(六大默认构造函数的揭破)-2
c++初阶------类和对象(六大默认构造函数的揭破)
|
4天前
|
存储 编译器 C语言
c++初阶------类和对象(六大默认构造函数的揭破)-1
c++初阶------类和对象(六大默认构造函数的揭破)
|
4天前
|
存储 编译器 C语言
c++初阶-------类和对象-2
c++初阶-------类和对象
|
4天前
|
编译器 C语言 C++
c++初阶-------类和对象-1
c++初阶-------类和对象
|
5天前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类