1. 程式人生 > >PAT-ADVANCED1090——Highest Price in Supply Chain

PAT-ADVANCED1090——Highest Price in Supply Chain

我的PAT-ADVANCED程式碼倉:https://github.com/617076674/PAT-ADVANCED

原題連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805376476626944

題目描述:

題目翻譯:

1090 供應鏈中的最高價格

供應鏈是零售商,經銷商和供應商構成的網路 - 每個人都參與將產品從供應商轉移到客戶。從一個根供應商開始,鏈上的每個人都以價格P從一個供應商處購買產品,並以高於P的r%的價格出售或分銷它們。只有零售商才會面對客戶。 假設供應鏈中的每個成員除了根供應商之外只有一個供應商,並且沒有供應環。現在給定供應鏈,您需要給出所有零售商中的最高價格。

輸入格式:

每個輸入檔案包含一個測試用例。在每個測試用例中,第一行包含3個正整數:N(<= 10 ^ 5),供應鏈中的總節點數(節點編號為0 ~ N - 1,根結點編號為0);P,代表商品的單位價格;以及r,代表每個經銷商或零售商的價格增量百分比。下一行包含N個數字,每個數字Si代表了編號為i的經銷商的供應商。根節點Sroot的供應商定義為-1。一行中的所有數字由一個空格分隔。

輸出格式:

對每個測試用例,在一行中輸出所有零售商中的最高價格,精確到2位小數,以及出售這個價格的零售商數目。兩個數字間用一個空格分隔。題目保證這個價格不會超過10 ^ 10。

輸入樣例:

9 1.80 1.00
1 5 4 4 -1 4 5 3 6

輸出樣例:

1.85 2

知識點:樹的深度優先遍歷、樹的廣度優先遍歷

思路一:深度優先遍歷的同時記錄節點的層級

時間複雜度和空間複雜度均是O(N)。

C++程式碼:

#include<iostream>
#include<vector>
#include<cmath>

using namespace std;

struct node{
	vector<int> child;
};

int N;
double P;
double r;
node Node[100000];
int countLevel[100000] = {0};	//第i層有countLevel[i]個葉子節點

void dfs(int nowVisit, int level); 

int main(){
	cin >> N >> P >> r;
	int num;
	int root;
	for(int i = 0; i < N; i++){
		cin >> num;
		if(num == -1){
			root = i;
			continue;
		}
		Node[num].child.push_back(i); 
	}
	dfs(root, 0);
	int maxLevel;
	for(int i = N; i >= 0 ; i--){
		if(countLevel[i] != 0){
			maxLevel = i;
			break;
		}
	}
	printf("%.2lf %d\n", pow(1 + r / 100, maxLevel) * P, countLevel[maxLevel]);
	return 0;
} 

void dfs(int nowVisit, int level){
	if(Node[nowVisit].child.size() == 0){
		countLevel[level]++;
		return;
	}
	for(int i = 0; i < Node[nowVisit].child.size(); i++){
		dfs(Node[nowVisit].child[i], level + 1);
	}
}

C++解題報告:

思路二:廣度優先遍歷的同時為每個節點新增層級資訊

時間複雜度和空間複雜度均是O(N)。

C++程式碼:

#include<iostream>
#include<vector>
#include<cmath>
#include<queue>

using namespace std;

struct node{
	int level;
	vector<int> child;
};

int N;
double P;
double r;
node Node[100000];

void bfs(int nowVisit); 

int main(){
	cin >> N >> P >> r;
	int num;
	int root;
	for(int i = 0; i < N; i++){
		cin >> num;
		if(num == -1){
			root = i;
			continue;
		}
		Node[num].child.push_back(i); 
	}
	bfs(root);
	int maxLevel = 0;
	for(int i = 0; i < N ; i++){
		if(Node[i].level > maxLevel){
			maxLevel = Node[i].level;
		}
	}
	int countMaxLevel = 0;
	for(int i = 0; i < N; i++){
		if(Node[i].level == maxLevel){
			countMaxLevel++;
		}
	}
	printf("%.2lf %d\n", pow(1 + r / 100, maxLevel) * P, countMaxLevel);
	return 0;
} 

void bfs(int nowVisit){
	queue<int> q;
	Node[nowVisit].level = 0;
	q.push(nowVisit);
	while(!q.empty()){
		int now = q.front();
		q.pop();
		for(int i = 0; i < Node[now].child.size(); i++){
			Node[Node[now].child[i]].level = Node[now].level + 1;
			q.push(Node[now].child[i]);
		}
	}
}

C++解題報告: