題目
https://www.patest.cn/contests/pat-a-practise/1079
題意:將零售商-經銷商-供應商這條鏈抽象爲一棵樹;供應商作爲根節點,出貨物的價格爲p,然後從根結點開始每往下走一層,該層的貨物價格將會在父親結點的價格上增加r%,給出每個葉結點(即零售商)的貨物量,求他們的價格之和。
解題思路
供應商-經銷商-零售商三者的關係可以看作是樹的根節點-內部節點-葉子結點的關係。因此問題就轉化成求每個葉子結點的層號,然後乘以相應係數,累加即可。
一次BFS/DFS解決,DFS代碼比較簡潔。
AC代碼
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int maxn = 100005;
vector<int> follow[maxn]; //記錄節點i的後續節點
int level[maxn]; //節點的層次
int visited[maxn] = {false};
double sale[maxn] = {0}; //零售商的編號集合
vector<int> retail; //零售商i的賣出數量
void BFS(int s)
{
queue<int> q;
q.push(s);
visited[s] = true;
level[s] = 0; //根節點層號爲0
int out, son;
while (!q.empty())
{
out = q.front(); q.pop();
for (int i = 0; i < follow[out].size(); ++i)
{
son = follow[out][i];
if (!visited[son]) //保證子節點沒訪問過
{
level[son] = level[out] + 1; //子節點層次爲父節點層次+1
visited[son] = true;
q.push(son);
}
}
}
}
void DFS(int index, int depth)
{
if (follow[index].size() == 0) //到達葉子結點
{
level[index] = depth; //也可以直接在這裏累加到ans
return;
}
for (int i = 0; i < follow[index].size(); ++i) //對每個子節點搜索
DFS(follow[index][i], depth+1);
}
int main()
{
int n;
double p, r;
int cnt, tmp;
cin >> n >> p >> r;
for (int i = 0; i < n; ++i) //處理每個編號爲i的節點
{
cin >> cnt;
if (cnt == 0) //葉子結點
{
cin >> sale[i];
retail.push_back(i); //零售商的編號集合
continue;
}
for (int j = 0; j < cnt; ++j)
{
cin >> tmp;
follow[i].push_back(tmp);
}
}
BFS(0); //BFS
//DFS(0, 0); //DFS
double ans = 0;
for (int i = 0; i < retail.size(); ++i) //累加零售商的售價
{
tmp = retail[i];
ans += sale[tmp] * p * pow(1.0+r/100, level[tmp]);
}
printf("%.1f\n", ans);
return 0;
}