首页 > 试题广场 >

Total Sales of Supply Chain (2

[编程题]Total Sales of Supply Chain (2
  • 热度指数:3680 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- 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. Only the retailers will face the customers.
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 total sales from all the retailers.

输入描述:
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 their ID's are numbered from 0 to N-1, and the root supplier's ID is 0); P, the unit price given by the root supplier; and r, the percentage rate of price increment for each distributor or retailer.  Then N lines follow, each describes a distributor or retailer in the following format:
Ki ID[1] ID[2] ... ID[Ki]
where in the i-th line, Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID's of these distributors or retailers. Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after Kj. All the numbers in a line are separated by a space.


输出描述:
For each test case, print in one line the total sales we can expect from all the retailers, accurate up to 1 decimal place.  It is guaranteed that the number will not exceed 1010.
示例1

输入

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

输出

42.4
/*
https://www.nowcoder.com/questionTerminal/6dc751a09c1f45ad84e02aa778c1e8c4
Total Sales of Supply Chain (25)   2018-12-20
General mean: Give you a A supply chain, require the total price of the last of ihis chain.
Result: Cost about 40 min, And get acpeted in first shoot. In it problm the double-type don't 
need to compared so it dont need to worry about the loss of accuracy. Both DFS and BFS is avaliable
but it is obvious that DFS can save more time. Easy problem.
*/
#include<iostream>
#include<string.h>
#include<vector>
#include<string>
using namespace std;
const int maxn = 100009;
int per[maxn];
int sell[maxn];        //more than zero if it is end of the chain
double pri[maxn];
double ans = 0.0;
int N;
double P, R;      // initial price and rate
double dfs(int p){
    int fater = per[p];
    return (pri[p] > 0 ? pri[p] : pri[p] = dfs(fater)*R);
}
int main(){
    cin >> N >> P >> R;
    R = (100 + R) / 100;
    for (int mun, next,i=0 ; i < N; i++){
        cin >> mun;
        if (mun == 0) cin>>sell[i];
        for (int j = 0; j < mun; j++){
            cin >> next;
            per[next] = i;
        }
    }
    per[0] = -1;
    pri[0] = P;
    for (int i = 0; i < N; i++){
        if (sell[i]>0) ans += sell[i] * dfs(i);
    }
    printf("%.1f\n", ans);
    return 0;
}


发表于 2018-12-20 21:05:42 回复(0)
思路:建立数 vector<struct tree> v;中 下标 表示第几个供应商。
每个供应商有结构体中的parent 表示的父亲节点。如果parent == NULL 表示的是已经遍历到
了根节点。
题目的大意就是 其实把第一个验证以后后面的就比较方便的计算了
10(供应链的人数) 1.80(价格) 1.00(增加的百分比)
3 2 3 5 第0行表示 总共有三个供应商 2 3 5 在 0 那里拿货
1 9     第1行表示 总共有1个供应商 9 在 1 那里拿货
1 4
1 7
0 7     第4行表示 4 是一个零售商 他销售的货物总数 是7 以下 基本比较雷同
2 6 1
1 8
0 9
0 4
0 3


建立的树             0
                     |-2     3        5
                       |-4   |-7      |- 1        6
                                         |- 9     |-8
然后就可以计算了
#include <iostream>
#include <fstream>
#include <vector>
#include <math.h>
#include <iomanip>
using namespace std;

struct tree
{
    struct tree * parent;
    int data; // 存有多少货物
};


#define Debug
#ifdef Debug
ifstream ifile("case.txt");
#define cin ifile
#endif


int level = 0;
int DFS(vector<struct tree> & v, struct tree *p)
{
    if (p->parent == NULL)
        return level;
    level++;
    return DFS(v, p->parent);
}




int main()
{
    int n;
    double price, precentage;
    cin >> n >> price >> precentage;
    vector<struct tree> v(n);
    v[0].parent = NULL;
    struct tree tmp;
    for (int i = 0; i < n; i++)
    {
        int flag;
        cin >> flag;
        if (flag != 0)
        {
            int data;
            for (int j = 0; j < flag; j++)
            {
                cin >> data;
                v[data].parent = &v[i];
            }
        }
        else
        {
            // 输入货物数量
            cin >> v[i].data;
        }
    }
    // 树在这里已经建立完毕了  root 节点是 0 节点
    double sum=0;
    for(int i=0; i<n; i++)// 找出所有的叶节点然后遍历上去,虽然这个不是一个很好的方法,但是应该能做
        if (v[i].data != 0)
        {
            level = 0;
            level = DFS(v, &v[i]);
            sum += v[i].data * price * pow(1.00+precentage/100, level);
        }
    cout << fixed <<setprecision(1) << sum << endl;
    system("pause");
}

发表于 2018-08-27 13:02:31 回复(0)
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <map>
#include <iomanip>
#include <sstream>
using namespace std;

//1079 Total Sales of Supply Chain
//uid编号0~n-1,<10^5
//树形结构

int n;
double p, r;
int k, uid, amt;
double total_, tmp_;
const int maxn = 100005;

class node {
public:
	double price;
	int amt;
	vector<int> nxt;
	node():amt(0){}
};

node net[maxn];

int main() {
	cin >> n >> p >> r;
	net[0].price = p;


	for (int i = 0; i < n; ++i) {
		scanf("%d", &k);
		if (k == 0) {
			scanf("%d", &amt);
			net[i].amt = amt;
			continue;
		}
		for (int j = 0; j < k; ++j) {
			scanf("%d", &uid);
			net[i].nxt.push_back(uid);
		}
	}

	//跑网络
	queue<int> q;
	q.push(0);
	int cur, len, sub_;
	while (!q.empty()) {
		cur = q.front();
		q.pop();
		len = net[cur].nxt.size();
		if (len == 0) {
			tmp_ = net[cur].price*net[cur].amt;
			total_ += tmp_;
			continue;
		}
		for (int i = 0; i < len; ++i) {
			sub_ = net[cur].nxt[i];
			net[sub_].price = net[cur].price *(1 + r * 0.01);
			q.push(sub_);
		}
	}
	//保留一位小数
	cout << fixed <<setprecision(1)<< total_;

	return 0;
}

编辑于 2020-02-24 10:10:31 回复(0)

#include <iostream>
#include <queue>
#include <vector>
#include <cmath>
usingnamespacestd;
const int maxn=100010;
int n,num;
double rootprice,increase,ans=0;
struct node{
    double value,level;
    vector<int> child;
}Node[maxn];
void layerOrder(int root){
    queue<int> q;
    Node[root].level=0;
    q.push(root);
    while(!q.empty ()){
        int now=q.front();
        q.pop();
        for(int i=0;i<Node[now].child.size();i++){
            int child=Node[now].child[i];
            Node[child].level=Node[now].level+1;
            q.push(child);
        }
        if(Node[now].child.size()==0)
            ans+=rootprice*Node[now].value*pow(increase,Node[now].level);
    }
}
int main(){
    cin>>n>>rootprice>>increase;
    increase=increase/100+1;
    for(int i=0;i<n;i++){
        int childnum;cin>>childnum;
        if(childnum!=0){
            for(int j=0;j<childnum;j++){
                cin>>num;
                Node[i].child.push_back(num);
            }
        }
        else cin>>Node[i].value;
    }
    layerOrder(0);
    printf("%.1f",ans);
    return 0;
}

编辑于 2019-01-17 17:17:42 回复(0)
//dfs爆搜即可
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n;double p,r,ans;
vector<int> G[maxn];
int sum[maxn];
void dfs(int rt,int step){
    int ok=1;
    for(int i=0;i<G[rt].size();++i){
        int v=G[rt][i];ok=0;
        dfs(v,step+1);
    }
    if(ok){
        ans+=p*pow(1+r*0.01,step)*sum[rt];    
    }    
}
int main(){
    scanf("%d %lf %lf",&n,&p,&r);
    for(int i=0,x;i<n;++i){
        scanf("%d",&x);
        if(x>0){
            for(int j=1,y;j<=x;++j)
                scanf("%d",&y),G[i].push_back(y);
        }else{
            scanf("%d",&x);
            sum[i]=x;                
        }
    }
    dfs(0,0);printf("%.1f\n",ans);    
    return 0;
} 

发表于 2018-03-05 10:22:20 回复(0)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>

using namespace std;

int main()
{     int n;     double p,r,total=0;     cin>>n>>p>>r;     vector<int> data(n,0);     vector<int> retailer(100001,0);     for(int i=0;i<n;i++)     {         int size;         cin>>size;         if(size!=0)         {             for(int j=0;j<size;j++)             {                 int t;                 cin>>t;                 data[t] = i;             }         }else             cin>>retailer[i];     }          for(int i=0;i<n;i++)     {         if(retailer[i]!=0)         {             double y = p*retailer[i];             int m = data[i];             while(m!=0)             {                 y *= (1+r/100);                 m = data[m];             }             total += y*(1+r/100);         }     }     printf("%.1f", total);     return 0;
}


发表于 2018-02-21 01:28:44 回复(0)
#include<bits/stdc++.h>
using namespace std;

const int Max=1e5+10;
int n;
double p,r,ans;

struct Node {
	double data;
	vector<int> child;
} node[Max];

void DFS(int index,int depth) {
	if(node[index].child.size()==0) {
		ans+=node[index].data*pow(1+r,depth);
		return ;
	}
	for(int i=0; i<node[index].child.size(); i++) {
		DFS(node[index].child[i],depth+1);
	}
}

int main() {
	scanf("%d %lf %lf",&n,&p,&r);
	r/=100;
	for(int i=0; i<n; i++) {
		int k;
		scanf("%d",&k);
		if(k==0) scanf("%lf",&node[i].data);
		else {
			for(int j=0; j<k; j++) {
				int ch;
				scanf("%d",&ch);
				node[i].child.emplace_back(ch);
			}
		}
	}
	DFS(0,0);
	printf("%.1f\n",p*ans);
	return 0;
}

发表于 2022-11-23 17:46:22 回复(0)

@[toc]

与这题非常类似的题目,我用的dfs解的-----Highest Price in Supply Chain

题目


OJ平台

题目翻译

  • 关键句意:

where in the i-th line, Ki is the total number of distributors or retailers who receive products from supplier i, and is then followed by the ID's of these distributors or retailers.
其中,在第i行中,Ki是从供应商i接收产品的分销商或零售商的总数,然后是这些分销商或零售商的ID。(注意i是它们的供应商!)

Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after Kj.
Kj为0意味着第j个成员是零售商,那么产品的总数量将在Kj之后给出。其实就是为0就代表它没有继续分销,直接开始零售了,接下来给出的就是他所进货的多少了。

代码详解

输入处理

void Input() {
    ios::sync_with_stdio(false);
    cin >> N >> p >> r;
    for (int i = 0; i < N; i++) { /*建树*/
        int t; cin >> t;
        if (t)
            while (t--) {
                int n; cin >> n; //更新它的子节点
                node[i].emplace_back(n);
            }
        else { //记录结束的结点(零售商)以及它的购买数量
            int n ; cin >> n;
            mp.emplace_back(make_pair(i, n));
        }
    }
}

输出处理

先用bfs进行一次层序更新一下对应结点的增长率!再进行答案的更新。

void bfs() {
    Q.push(0); //利用bfs得出层级更新利率rr
    while (!Q.empty()) {
        int x = Q.front(); Q.pop();
        for (auto && t : node[x]) {
            rr[t] = rr[x] + rr[x] * (r / 100.0);
            Q.push(t);
        }
    }
}
void print() {
    bfs();
    double res = 0;
    for (auto && t : mp) {
        res += rr[t.first] * (double)t.second * p;
    }
    cout << fixed << setprecision(1) << res;
}

汇总代码提交

效率不错!

#include<bits/stdc++.h>
using namespace std;
#define MaxN 100001
int N;
double p, r;
vector<int> node[MaxN];
queue<int> Q;

//这道题仍然是以0为根节点,而结束的结点它也告诉你了,在个数为0的时候作结束。
//在结点为0的时候,它最终给出它的大小(就是这条线得到的商品数量),而销售额就是商品数量*商品价格*增长率
vector<pair<int, int>>mp;
vector<double>rr(MaxN, 1); //存储每个结点得到的增长利润
void Input() {
    ios::sync_with_stdio(false);
    cin >> N >> p >> r;
    for (int i = 0; i < N; i++) { /*建树*/
        int t; cin >> t;
        if (t)
            while (t--) {
                int n; cin >> n; //更新它的子节点
                node[i].emplace_back(n);
            }
        else { //记录结束的结点以及它的购买数量
            int n ; cin >> n;
            mp.emplace_back(make_pair(i, n));
        }
    }
}

void bfs() {
    Q.push(0); //利用bfs得出层级更新利率rr
    while (!Q.empty()) {
        int x = Q.front(); Q.pop();
        for (auto && t : node[x]) {
            rr[t] = rr[x] + rr[x] * (r / 100.0);
            Q.push(t);
        }
    }
}
void print() {
    bfs();
    double res = 0;
    for (auto && t : mp) {
        res += rr[t.first] * (double)t.second * p;
    }
    cout << fixed << setprecision(1) << res;
}
int main() {
    Input();
    print();
    return 0;
}
发表于 2021-09-27 20:49:48 回复(0)
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int n;
double p,r;
vector<int> q;
vector<int> temp;
vector<vector<int>> chain;
int main(int argc, const char * argv[]) {
    cin>>n>>p>>r;
    q.push_back(0);
    int k,t;
    double price=0;
    int lay[10010];
    lay[0]=0;
    for (int i=0; i<n; i++) {
        cin>>k;
        temp.push_back(k);
        if (k!=0) {
            for (int j=0; j<k; j++) {
                cin>>t;
                temp.push_back(t);
            }
        }else{
            cin>>t;
            temp.push_back(t);
        }
        chain.push_back(temp);
        temp.clear();
    }
    while (q.size()!=0) {
        for (int i=1;i<=chain[*q.begin()][0] ; i++) {
            q.push_back(chain[*q.begin()][i]);
            lay[chain[*q.begin()][i]]=lay[*q.begin()]+1;
        }
        if (chain[*q.begin()][0]==0) {
            price+=chain[*q.begin()][1]*p*pow(1+0.01*r, lay[*q.begin()]);
        }
        q.erase(q.begin());
    }
    int p1=int(price*100)%10;
    int p2;
    if (p1<5) {
        p2=int(price*100)/10;
        price=p2/10.0;
        printf("%.1f\n", price);
    }else{
        p2=int(price*100)/10+1;
        price=p2/10.0;
        printf("%.1f\n", price);
    }
    return 0;
}

发表于 2021-02-17 22:27:16 回复(0)
我,,,设置成了rate+=rate/100,哪个用例是1,这样就是对的,然后找bug找半天。。。。。我咋这么菜,啥都能遇上
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 100001;
vector<int>G[MAXN];
int customer[MAXN];
int num;
double price, rate;
double sales = 0;
void dfs(int current, double p) {
	if (G[current].empty()) {
		sales += p * customer[current];
	}
	for (int i = 0; i < G[current].size(); i++) {
		dfs(G[current][i], p * rate);
	}
}

int main() {
	//freopen("C:\\Users\\47\\Desktop\\1.txt", "r", stdin);
	fill(customer, customer + MAXN, 0);
	cin >> num >> price >> rate;
	rate = 1 + rate / 100;
	for (int i = 0; i < num; i++) {
		int n;
		cin >> n;
		if (!n) {
			cin >> customer[i];
			continue;
		}
		while (n--) {
			int number;
			cin >> number;
			G[i].push_back(number);
		}
	}
	dfs(0, price);
	printf("%.1lf", sales);
}


 

编辑于 2020-02-28 10:45:37 回复(0)
a = input().split()
c,d,m = 0,{},[]
for i in range(int(a[0])):
    b = list(map(int,input().split()))
    if b[0]:
        for j in b[1:]:
            d[j] = i
    else:
        m.append([i,b[1]])

for i in m:
    j = 0
    while i[0] in d:
        j += 1
        i[0] = d[i[0]]
    c += i[1] * float(a[1]) * (float(a[2]) / 100 + 1) ** j
        
print('{:.1f}'.format(c))
pta上超时4个,连数据都输不完,还让不让人活啦@_@
编辑于 2020-02-23 22:38:14 回复(0)
#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int>v[100005];
int size[100005];
int isR[100005];
int N;double p,r;
double all=0;
void dfs(int from,double p){
    if(v[from][0]==-1){
        double allprize=p*size[from];
        all=all+allprize;
    }
    else{
        for(int i=0;i<v[from].size();i++)
            dfs(v[from][i],p*(1+r/100));
    }       
}
int main(){
    memset(size,0,sizeof(size));
    memset(isR,0,sizeof(isR));
    scanf("%d%lf%lf",&N,&p,&r);
    for(int i=0;i<N;i++){
        int number;
        scanf("%d",&number);
        if(number!=0){
            for(int j=0;j<number;j++){
                int relation;
                scanf("%d",&relation);
                v[i].push_back(relation);
            }
        }else if(number==0){
            v[i].push_back(-1);
            isR[i]=-1;
            int size_; 
            scanf("%d",&size_);
            size[i]=size_;
        }
    }
    dfs(0,p);
    printf("%.1lf",all);

发表于 2020-01-16 17:58:27 回复(0)
 Kj being 0 means that the j-th member is a retailer, then instead the total amount of the product will be given after Kj.
这个instead真的秀。
什么供应商、经销商、零售商全是用来模糊题意的。

题目BFS就行,跟层级相关的算法用我这个模板感觉不错。

#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
#include <climits>
#include <iomanip>
#include <map>
using namespace std;

int main(){
    int N;
    double P, r;
    cin >> N >> P >> r;
    vector<vector<int>> chain(N);
    map<int, int> amount;
    for(int i = 0; i < N; i++){
        int k;
        cin >> k;
        if(k == 0){
            cin >> amount[i];
        }
        for(int j = 0; j < k; j++){
            int t;
            cin >> t;
            chain[i].push_back(t);
        }
    }
    queue<int> que;
    que.push(0);
    int current_level = 0, current_cnt = 1, next_cnt = 0;
    double tot = 0;
    while(!que.empty()){
        int x = que.front(); que.pop();
        if(chain[x].empty()){
            tot += amount[x] * P * pow(1 + r / 100, current_level);
        }
        else{
            for(auto d : chain[x]){
                que.push(d);
                next_cnt++;
            }
        }
        current_cnt--;
        if(current_cnt == 0){
            current_level++;
            current_cnt = next_cnt;
            next_cnt = 0;
        }
    }
    cout << fixed;
    cout << setprecision(1);
    cout << tot << endl;
}



发表于 2019-08-23 15:13:00 回复(0)
使用float竟然不行,必须用double !
不需要用什么广度或者深度优先遍历,直接从叶节点(零售商)向上回溯到根节点得到路径长度,然后将所有叶节点累加就可以了。
发表于 2019-07-14 20:31:48 回复(1)
#include<iostream>
#include<queue>
#include<vector>
#include<cmath>
#include<iomanip>
using namespace std;
int main() {
    int n,i,k=0;
    double p, r,sum=0;
    cin >> n >> p >> r;
    int leaf[100005] = {0};
    vector<int> vec[100005];
    for (i = 0; i < n; i++) {
        int ki;
        cin >> ki;
        if (ki == 0) {
            int mount;
            cin >> mount;
            leaf[i] = mount;
            continue;
        }
        else {
            for (int j = 0; j < ki; j++) {
                int node;
                cin >> node;
                vec[i].push_back(node);
            }
        }
    }
    //广度优先遍历
    int level = 0,cnt_pre =1, cnt_now;
    queue<int> q;
    q.push(0);
    while (!q.empty()) {
        level++;
        cnt_now = 0;
        while (cnt_pre--) {
            int nod = q.front();
            q.pop();
            int count = vec[nod].size();
            if (count == 0) {         //已到达叶子节点
                sum = sum + p * leaf[nod] * pow(1 + r * 0.01, level - 1);
            }
            else {
                for (i = 0; i < count; i++, cnt_now++)
                    q.push(vec[nod][i]);
            }
        }
        cnt_pre = cnt_now;
    }
    cout << setiosflags(ios::fixed) << setprecision(1) << sum << endl;
    return 0;
}

编辑于 2019-07-07 13:19:58 回复(0)
total sales 必须是double类型,float类型精确度不够,导致大概一半的错误
发表于 2019-05-30 11:09:24 回复(0)
def dfs(root,bu):
    global res
    boo = True
    for i in range(0,len(lst[root])):
        rt = lst[root][i]
        boo = False
        dfs(rt,bu+1)
    if boo:
        res+=p*pow(1+r*0.01,bu)*sa[root]
res = 0.0
n,p,r = map(float,input().split())
lst,sa,con = [],[],0
for i in range(0,int(n)):
    temp = list(map(int,input().split()))
    if temp[0]!=0:
        con+=1
        lst.append(temp[1:])
        sa.append([])
    else:
        sa.append(temp[1])
        lst.append([])
dfs(0,0)
print("%.1f"%res)

发表于 2018-12-02 17:18:22 回复(0)

/读题一小时做题5分钟,刚开始理错误,认为不确定供应商零售商,结果尴尬的想了很久
最后发现只需要建立树即可,只要在第n行的序号就是孩子,第一个数是总数,然后建立一颗树
最后用队列进行搜索然后得出价格
/

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int []start;
static int []end;
static String []temp_start;
static boolean flag;
static int N;
public static void main(String[] args) throws IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer tokenizer;
tokenizer = new StringTokenizer(reader.readLine());
int N = Integer.parseInt(tokenizer.nextToken());
double P = Double.parseDouble(tokenizer.nextToken());
double R = Double.parseDouble(tokenizer.nextToken()) / 100 + 1;
Node[] nodes = new Node[N];
int[] child = new int[N];

    for (int i = 0; i != N; i++)
    {
        nodes[i] = new Node();
    }
    for(int i=0;i!=N;i++)
    {
        tokenizer = new StringTokenizer(reader.readLine());
        int temp = Integer.parseInt(tokenizer.nextToken());

         if (temp == 0)
        {
            child[i] = Integer.parseInt(tokenizer.nextToken());
            continue;
        }
        else if (temp >= 1)
        {

            for (int j = 0; j < temp; j++)
            {
                nodes[i].child.add(nodes[Integer.parseInt(tokenizer.nextToken())]);
            }

        }
    }

    Queue<Node> queue=new LinkedList();
    queue.add(nodes[0]);
    int next=1,count,layer=-1;
    double priceall=0;
    do {
        count=next;
        next=0;
        layer++;
        for(int j=0;j<count;j++)
        {
            Node temp =  queue.poll();
            if (!temp.child.isEmpty()) {
                next += temp.child.size();
                queue.addAll(temp.child);
            }
            else {


                int i = 0;
                for (; i < N; i++) {
                    if (nodes[i] == temp) {
                        break;
                    }
                }
                priceall+= child[i] * P * Math.pow(R, layer);
                continue;

            }

        }



    }while (next!=0);
    System.out.printf("%.1f",priceall);

}
public static class Node{
    List <Node> child;
    public Node()
    {
        child=new ArrayList<Node>();
    }

}

}

发表于 2018-10-16 20:36:40 回复(0)
n, p, r = input().split()
n, p, r = int(n), float(p), float(r)
L = [[] for i in range(n)]
ret = [0 for i in range(n)]
for i in range(n):
    line = list(map(int, input().split()))
    if line[0] > 0:
        L[i].extend(line[1:])
    elif line[0]==0:
        ret[i] = line[1]

lev, cur, ans = 0, [0], 0.0
while cur:
    lev += 1
    now = [y for x in cur for y in L[x]]
    for t in now:
        if ret[t] > 0:
            ans += ret[t] * p * (1+r/100)**lev
    cur = now

print('%.1f' % ans)

发表于 2018-04-19 15:13:41 回复(0)
题目描述:所谓的供应链就是指一张涵盖零售商、经销商、供应商的一张网络,每个成员都参与在将产品由工厂流入顾客手中的过程中。
         从一个源供应商开始,供应链上的每个成员从提供者手里用价格P购买商品,然后以高于P百分之r的价格售给下家。只有零售商是面向顾客的
         假设供应链上除了源供应商外的每个成员都只面向一个供应商且供应链中没有任何环路。
         现在给你一个供应链,你需要计算出所有零售商售出所有商品的总额。

输入描述:每次输入包含一个用例,对于每个用例,第一行包括三个正整数:N(<=10^5),N是供应链上所有成员的个数(所有成员的ID从0到N-1编号,根供应商的ID为0)
         P为根供应商给出的价格,r为每次倒卖倒买时价格的涨幅(如买入价格为p则转手价格为p*(1+r))。
         接下来跟着N行,每行以如下格式描述了经销商或零售商的信息:Ki ID[1] ID[2] ... ID[Ki]
         第i行中,Ki指从ID为i的经销商手中进货的零售商和经销商的总数,接下来的ID就是表明有哪些经销商和零售商。
         Kj为0代表第j个成员为零售商(直接面对顾客,无下家了),然后产品总数会在Kj之后给出.所有数据之间隔着空格

输出描述:对每个用例,在一行内输出所有零售商的总销售额,精确到小数点后一位,我们保证这个数值不会超过10^10

(本人初学者,菜鸟,不会用太高端的算法,只能用易于理解的遍历来解决了。。。。。)
思路:设源供应商为根结点,旗下所有下家结尾其子孙,因为每个经销商或零售商都只面向一个上家且没有环路(题目描述)所以可以用树(图)来解决这个问题
      1.根据输入建立图,并让根结点附带一个单位商品价值,并把根结点及其商品数记录在MAP中
      2.利用广度优先遍历,把每个结点的单位商品价值设为其前一个结点价值乘以(1+r)。
      3.遍历MAP,把对应结点单价乘以库存并累加起来得出答案。
PS:其实就是按图思路来计算,不过一定要考虑清楚使用什么存储方式来存储这个数据结构,在此我先试试用邻接表方式(绝壁稀疏图)。。。。试试就试试。。。     

#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<queue>
#include<vector>
#include<map>
#define MAXSIZE 100000
using namespace std;

map<int, int> Store;
double P, r;

typedef struct arcnode{
    int AdjVertex;
    struct arcnode* nextArc;
}*ArcNode;

typedef struct {
    double Price;
    struct arcnode* firstArc;
}Vertex;

typedef struct graph {
    Vertex vertex[MAXSIZE];
    int V_num;
    int A_num;
}AdjList,*GRAPH;

int FirstAdjNode(GRAPH G, int v) {
    if (G->vertex[v].firstArc == NULL)
        return -1;
    else
        return G->vertex[v].firstArc->AdjVertex;
}

int NextAdjNode(GRAPH G, int v, int w) {
    if (G->vertex[v].firstArc == NULL)
        return -1;
    ArcNode arc;
    for (arc = G->vertex[v].firstArc;arc!=NULL && arc->AdjVertex != w; arc = arc->nextArc);
    if (arc->nextArc == NULL || arc == NULL)
        return -1;
    else
        return arc->nextArc->AdjVertex;
}

double BFS(GRAPH G) {
    queue<int> Q;
    vector<int> Visited(G->V_num, false);
    double price = 0;
    int v, w;
    v = 0;
    Q.push(v);
    Visited[v] = true;
    while (!Q.empty()) {
        v = Q.front();
        Q.pop();
        w = FirstAdjNode(G, v);
        while (w != -1) {
            if (!Visited[w]) {
                G->vertex[w].Price = G->vertex[v].Price * (1 + r);
                Visited[w] = true;
                Q.push(w);
            }
            w = NextAdjNode(G, v, w);
        }
    }
    for (map<int, int>::iterator its = Store.begin(); its != Store.end(); ++its) {
        price += G->vertex[its->first].Price * its->second;
    }
    return price;
}

GRAPH GenerateG(){
    int vnum;
    int anum;
    int cnum;
    int ID;

    ArcNode Arc = NULL;
    GRAPH G = (AdjList*)malloc(sizeof(AdjList));
    cin >> vnum >> P >> r;
    G->A_num = 0;
    G->V_num = vnum;
    r /= 100;
    for (int i = 0; i < vnum; ++i) {
        G->vertex[i].Price = P;
        G->vertex[i].firstArc = NULL;
    }
    for (int i = 0; i < vnum; ++i) {    //开始读取供应链信息
        cin >> cnum;
        if (cnum == 0) {                //若该节点为零售商,无下家
            cin >> ID;
            Store[i] = ID;              //则记录销售商品总数
        }
        for (int j = 0; j < cnum; ++j) {                //记录各下家
            cin >> ID;
            Arc = (arcnode*)malloc(sizeof(arcnode));
            Arc->AdjVertex = ID;
            //if (G->vertex[i].firstArc == NULL)
            //    Arc->nextArc == NULL;
            //else
                Arc->nextArc = G->vertex[i].firstArc;
            G->vertex[i].firstArc = Arc;
        }
    }
    return G;
}

int main() {
    GRAPH G = GenerateG();
    cout << fixed << setprecision(1) << BFS(G) << endl;
    system("pause");
    return 0;
}


发表于 2018-03-02 23:15:26 回复(0)