1106 Lowest Price in 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 lowest price a customer can expect from some retailers.
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 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. All the numbers in a line are separated by a space.
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.
题目大意:在一个供应链(有向无权图)里,从供应商(源点)开始,每经过一个中间商就会加一次价格( P*(1+r%) ),消费者只能从零售商(叶节点)处购买产品,供应链不会形成环,求消费者最终可以拿到的最少的价位以及持此价格的零售商的个数。
思路:有很多方法,比如把供应链当成一棵树,找深度最浅的叶节点;我是把它作为一个有向无权图来考虑的,不管什么方法,总归是BFS或者DFS寻找叶节点,我使用的BFS(少用递归比较保险,毕竟要卡时间),把每个节点到源点的距离都算出来了,按理说找到最近的零售商就可以停止搜索了,但是考虑到测试点大概率会有遍历整张图的样例,所以说没必要优化了(其实是懒~),然后将零售商的距离排个序,找出最近的几个,算一下价格~
注意:价格变量要用double,因为float的精度不够,会卡住三个测试点。。
#include <iostream> #include <vector> #include <queue> #include <cmath> #include <algorithm> using namespace std; vector <int> G[100000]; void BFS(vector <int> &dist); int main() { int N, M, K; double P, r;//注意,float的精度不够,会卡住三个测试点!!! scanf("%d%lf%lf", &N, &P, &r); vector <int> dist(N, -1), retailer; for (int i = 0; i < N; i++) { scanf("%d", &K); if (K == 0) { retailer.push_back(i);//记录零售商 continue; } int u; for (int j = 0; j < K; j++) { scanf("%d", &u); G[i].push_back(u); } } BFS(dist); vector <int> rDist; for (int i = 0; i < retailer.size(); i++) rDist.push_back(dist[retailer[i]]);//记录零售商的加价程度,也就是price的系数的指数 sort(rDist.begin(), rDist.end());//排序 int ansDist = rDist[0], cnt = 1; for (int i = 1; i < rDist.size(); i++) { if (rDist[i] > ansDist) break; cnt++; } double price = pow(1 + r / 100.0, ansDist)*P; printf("%.4lf %d\n", price, cnt); return 0; } void BFS(vector <int> &dist) { int u, v; queue <int> Q; Q.push(0); dist[0] = 0; while (!Q.empty()) { u = Q.front(); Q.pop(); for (int i = 0; i < G[u].size(); i++) { v = G[u][i]; if (dist[v] == -1) { dist[v] = dist[u] + 1; Q.push(v); } } } }