1. 供应链价格峰值问题解析
供应链价格分析是商业决策中的关键环节,特别是在分销网络层级较多的行业。这个题目考察的是如何从供应链的树状结构中找出最高售价节点及其出现频率,属于典型的数据结构与算法应用场景。
我在处理类似供应链问题时发现,最核心的挑战在于如何高效遍历整个网络并准确记录价格变化。这不仅是编程能力的考验,更是对商业逻辑理解的检验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 问题建模与算法选择
2.1 数据结构设计
供应链通常呈现树状结构,每个节点代表一个分销商或零售商。我们需要:
- 使用邻接表存储节点关系
- 记录每个节点的价格转换率
- 维护当前层级和价格信息
实际应用中,我推荐使用vector<vector
2.2 核心算法实现
深度优先搜索(DFS)是这个场景的最优解:
cpp复制void dfs(int node, double currentPrice, int depth) {
if(tree[node].empty()) { // 叶子节点
if(currentPrice > maxPrice) {
maxPrice = currentPrice;
count = 1;
} else if(currentPrice == maxPrice) {
count++;
}
return;
}
for(int child : tree[node]) {
dfs(child, currentPrice * (1 + price[node]/100.0), depth + 1);
}
}
这个实现有几个关键点:
- 递归终止条件:遇到叶子节点时进行价格比较
- 价格传递:子节点价格 = 父节点价格 × (1 + 利润率)
- 使用全局变量记录最大值和出现次数
3. 性能优化与边界处理
3.1 输入处理技巧
PAT考试中,输入格式通常是:
code复制N P r
后续N行是各节点的父节点
我建议这样读取:
cpp复制cin >> N >> P >> r;
tree.resize(N);
int root = -1;
for(int i = 0; i < N; i++) {
int parent;
cin >> parent;
if(parent == -1) {
root = i;
} else {
tree[parent].push_back(i);
}
}
特别注意:
- 要正确识别根节点(父节点为-1)
- 价格转换率r需要除以100处理
- N=1时要特殊处理
3.2 浮点数精度问题
比较浮点数时不能直接用==,应该:
cpp复制const double EPS = 1e-8;
if(fabs(currentPrice - maxPrice) < EPS) {
count++;
} else if(currentPrice > maxPrice) {
maxPrice = currentPrice;
count = 1;
}
这个细节在实际考试中经常被忽视,导致部分测试用例无法通过。
4. 完整代码实现与测试
4.1 完整解决方案
cpp复制#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
vector<vector<int>> tree;
vector<int> price;
double maxPrice = -1.0;
int count = 0;
const double EPS = 1e-8;
void dfs(int node, double currentPrice) {
if(tree[node].empty()) {
if(fabs(currentPrice - maxPrice) < EPS) {
count++;
} else if(currentPrice > maxPrice) {
maxPrice = currentPrice;
count = 1;
}
return;
}
for(int child : tree[node]) {
dfs(child, currentPrice * (1 + price[node]/100.0));
}
}
int main() {
int N;
double P, r;
cin >> N >> P >> r;
tree.resize(N);
price.resize(N);
int root = -1;
for(int i = 0; i < N; i++) {
int parent;
cin >> parent;
if(parent == -1) {
root = i;
} else {
tree[parent].push_back(i);
}
price[i] = r;
}
if(N == 1) {
printf("%.2f 1", P);
return 0;
}
dfs(root, P);
printf("%.2f %d", maxPrice, count);
return 0;
}
4.2 测试用例设计
建议测试这些边界情况:
- 单节点供应链(N=1)
- 直线型供应链(每个节点只有一个子节点)
- 完全二叉树结构的供应链
- 所有叶子节点价格相同的情况
- 大规模数据测试(N=10^5)
5. 常见错误与调试技巧
5.1 典型错误类型
- 根节点识别错误:忘记处理parent=-1的情况
- 价格计算错误:没有将百分比r转换为小数
- 浮点比较问题:直接用==比较价格
- 初始条件错误:maxPrice初始值设置不当
- 输出格式错误:没有保留两位小数
5.2 调试建议
- 先打印整棵树的结构,确认输入读取正确
- 在dfs中添加调试输出,跟踪价格变化过程
- 对单个测试用例进行手工计算验证
- 特别注意N=1的特殊情况
我在实际编码中发现,使用VS Code的调试器设置条件断点非常有用,可以在特定节点暂停执行检查变量状态。
