單詞積累
increment 增量 增加
題目
A supply chain is a network of retailers(零售商), distributors(經(jīng)銷商), and suppliers(供應(yīng)商)-- everyone involved in moving a product from supplier to customer.
Starting from one root supplier, everyone on the chain buys products from one's supplier in a price P and sell or distribute them in a price that is r% higher than P. It is assumed that each member in the supply chain has exactly one supplier except the root supplier, and there is no supply cycle.
Now given a supply chain, you are supposed to tell the highest price we can expect from some retailers.
Input Specification:
Each input file contains one test case. For each case, The first line contains three positive numbers: N (≤105), the total number of the members in the supply chain (and hence they are numbered from 0 to N?1); P, the price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer. Then the next line contains N numbers, each number Si is the index of the supplier for the i-th member. S root for the root supplier is defined to be ?1. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the highest price we can expect from some retailers, accurate up to 2 decimal places, and the number of retailers that sell at the highest price. There must be one space between the two numbers. It is guaranteed that the price will not exceed 1010.
Sample Input:
9 1.80 1.00
1 5 4 4 -1 4 5 3 6結(jié)尾無空行
Sample Output:
1.85 2結(jié)尾無空行
思路
這是一個(gè)由零售商害驹、經(jīng)銷商與供應(yīng)商構(gòu)成的一般樹。需要找到最大深度蛤育,以及該深度存在的葉節(jié)點(diǎn)數(shù)宛官。
自己一開始對(duì)一般樹的掌握不很好,想到了用類似并查集的方法去做瓦糕,這個(gè)缺點(diǎn)是每次都是從葉節(jié)點(diǎn)處開始查找底洗,如果出現(xiàn)下圖所示的極端情況時(shí),時(shí)間復(fù)雜的是O(n 方)咕娄,最后一個(gè)樣例超時(shí)亥揖。
參考的做法是,用向量存儲(chǔ)孩子圣勒,這棵樹就可以表示為數(shù)組向量费变。數(shù)組中的第i個(gè)元素,就是以i為父節(jié)點(diǎn)的所有節(jié)點(diǎn)構(gòu)成的向量圣贸。最大深度只需從根節(jié)點(diǎn)處開始遍歷挚歧。
代碼1
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100001;
int num[maxn];
int father[maxn];
int height[maxn];
int N;
double P, r;
void inital() {
for (int i = 0; i < N; i++) {
father[i] = i;
height[i] = 0;
}
}
int findfather(int x) {
int times = 0;
while (father[x] != -1) {
x = father[x];
times++;
}
return times;
}
void Union(int a, int b) {
father[a] = b;
if (b != -1) height[b] = 1;
}
int main() {
cin>>N>>P>>r;
inital();
for (int i = 0; i < N; i++) {
scanf("%d", &num[i]);
Union(i, num[i]);
}
int res = 0;
int clu = 0;
for (int i = 0; i < N; i++) {
if(height[i] == 0) {
if(findfather(i) == res) clu++;
else if(findfather(i) > res) {
res = findfather(i);
clu = 1;
}
}
}
double price = P * pow(1 + r * 0.01, res);
printf("%.2f %d", price, clu);
}
代碼2(BFS)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100001;
vector<int> num[maxn];
int N;
double P, r;
int maxdepth = 0;
int clus = 0;
void BFS(int root, int depth) {
if (num[root].size() == 0) {
if (depth == maxdepth) {
clus++;
} else if (depth > maxdepth) {
clus = 1;
maxdepth = depth;
}
return;
}
for (int i = 0; i <num[root].size(); i++) {
BFS(num[root][i], depth + 1);
}
}
int main() {
cin>>N>>P>>r;
int root = -1;
int temp;
for (int i = 0; i < N; i++) {
cin>>temp;
if (temp == -1) root = i;
else {
num[temp].push_back(i);
}
}
if (root != -1) BFS(root, 0);
double price = P * pow(1 + r * 0.01, maxdepth);
printf("%.2f %d", price, clus);
}