1106サプライチェーンの最低価格(25分)
サプライチェーンは、小売業者、流通業者、およびサプライヤのネットワークです。サプライヤから顧客への製品の移動に関係するすべての人です。
あるルートサプライヤーから始めて、チェーンの全員が自分のサプライヤーから価格Pで製品を購入し、Pよりもr%高い価格で製品を販売または配布します。小売業者のみが顧客と向き合います。サプライチェーンの各メンバーには、ルートサプライヤを除いて、サプライヤが1つだけあり、サプライサイクルはないと想定されています。
サプライチェーンが与えられると、顧客が一部の小売業者に期待できる最低価格を伝えることになっています。
入力仕様:
各入力ファイルには、1つのテストケースが含まれています。いずれの場合も、最初の行には3つの正の数が含まれます:N(≤10^ 5)、サプライチェーンのメンバーの総数(したがって、それらのIDには0からN-1までの番号が付けられ、ルートサプライヤのIDは次のようになります。 0); P、ルートサプライヤーによって与えられた価格。r、各ディストリビューターまたは小売業者の価格上昇率。次に、N行が続き、それぞれが次の形式で販売業者または小売業者を表します。
K iID [1] ID [2]…ID [Ki]
ここで、i番目の行で、K iは、サプライヤーiから製品を受け取るディストリビューターまたは小売業者の総数であり、その後にこれらのディストリビューターまたは小売業者のIDが続きます。Kjが0の場合、j番目のメンバーが小売業者であることを意味します。行内のすべての数字はスペースで区切られます。
出力仕様:
各テストケースについて、一部の小売業者に期待できる最低価格、小数点以下4桁までの正確さ、および最低価格で販売する小売業者の数を1行で印刷します。2つの数字の間には1つのスペースが必要です。すべての価格が10超えないことが保証される
10
。
サンプル入力:
10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0
2 6 1
1 8
0
0
0
サンプル出力:
1.8362 2
トピックの主なアイデア:
ツリーの情報、ルートノードでの商品の価格P、および各下位層の価格の成長率%rが与えられると、リーフノードは小売業者を表し、すべての小売価格の最小値が必要であり、最低価格を提供できる小売業者の数
アルゴリズム分析:
深さ優先探索のテンプレート。minDepth、トラバースされるレベルの最小数、およびこのレベルの下のリーフノードの数を維持します。DFSのパラメーターはノード番号とレイヤー数であり、リーフノードがトラバースされると再帰が終了します。剪定に注意してください
ACコード
#include<bits/stdc++.h>
using namespace std;
int nodeNum,cnt;
double originalPrice, minDepth = 999999999, riseRate;
//找minDepth而不是minPrice,最后再计算minPrice,可以减少计算量
vector<vector<int>> retailer;
void DFS(int index,int layer){
if(layer>minDepth)
return;//剪枝,如果当前层数已经大于最小层数,则本次遍历的price一定不是最小的,可以舍去
if(retailer[index].size()==0){
//当size为0时,表示index对应的结点代表零售商
if(layer==minDepth)
cnt++;
else if(layer<minDepth){
minDepth = layer;
cnt = 1;
}
}
for (int i = 0; i < retailer[index].size();i++)
DFS(retailer[index][i], layer + 1);
}
int main(){
cin >> nodeNum >> originalPrice >> riseRate;
retailer.resize(nodeNum);
riseRate = 1 + 0.01 * riseRate;
int a, b;
for (int i = 0; i < nodeNum;i++){
cin >> a;
if(a!=0){
for (int j = 0; j < a;j++){
cin >> b;
retailer[i].push_back(b);
}
}
}
DFS(0, 0);
printf("%.4lf %d", originalPrice*pow(riseRate,minDepth), cnt);
}