PAT刷题之路——A1079 Total Sales of Supply Chain

其实是一道树题

从题目上看以为是一道dijskra题或者单纯的图论题,其实是一道建树和深搜问题

关键词: 树 DFS

PAT A1079 Total Sales of Supply Chain

原题如下

在这里插入图片描述
在这里插入图片描述

题目意思理解

该题中有三种人物:零售商、经销商、供应商。
每个人从供应者卖向消费者,从根供应者开始,每个在商业链上的人从供应者那里用 P P P价格买来然后以高于 P P P r % r\% r%的价格卖出或者经销它们。假设每一个在需求链上的成员有确定的供应者除了根供应者,无供应循环。
给出供应链,输出从零售商的所有买卖。
输入:
N:成员数量,0-N-1。P:根供应者的单位价格。 r:对每个经销商和零售商的利润。
接下来N行:
以下分别表示第 i i i个供应者的供应人数和其对应的ID,若 K j = 0 K_j=0 Kj=0说明其实零售商,之后输入其总共的产品数量。
K i K_i Ki ID[1]…ID[ K i K_i Ki]
输出:
输出所有零售商的总共收入,保留一位小数,不超过 1 0 10 10^{10} 1010.

自己的想法

零售商、经销商、供应商分别就代表叶节点、中间节点和根节点。
是一个多叉树问题,所以在建立树的结构时可以采用vector来存储该节点的后继节点。

  1. 首先遍历所有有供应商的节点并标注一下,未标注的自然就是根节点。
  2. 用深搜DFS将每个叶节点卖出去的价格存储并相加最后输出。

注意:P、r都为浮点数,且输出结果保留一位小数。

答案反馈

一次正确了!!!花了半个小时的时间。庆祝!!
在这里插入图片描述

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<set>
#include<queue>
#include<map>
#include<stack>
using namespace std;
const int maxn = 100005;
bool flag[maxn] = { false };
int n;
double p, r;
struct node {
	int data;
	vector<int> child;
}tree[maxn];
double sum = 0.0;
void DFS(int root,double p) {
	//cout << root << ' ' << p << endl;
	if (tree[root].child.empty()) { sum += tree[root].data*p; return; }
	for (int i = 0; i < tree[root].child.size(); i++) {
		DFS(tree[root].child[i],p*(1+0.01*r));
	}
}
int main() {
	cin >> n >> p >> r;
	for (int i = 0; i < n; i++) {
		int num;
		cin >> num;
		if (num == 0) {
			int p_num;
			cin >> p_num;
			tree[i].data = p_num;
		}
		else {
			for (int j = 0; j < num; j++) {
				int temp;
				cin >> temp;
				flag[temp] = true;
				tree[i].child.push_back(temp);
			}
		}
	}
	//找出根节点
	int root;
	for (root = 0; root < n; root++) {
		if (flag[root] == false)break;
	}
	//cout << root << endl;
	DFS(root,p);
	printf("%.1f\n", sum);
	return 0;
}

结语

其实看清楚题也没那么难嘛,嘿嘿

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值