PAT-ADVANCED1090——Highest Price in Supply Chain
阿新 • • 發佈:2018-11-06
我的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++解題報告: