PAT A1090 Highest Price in Supply Chain

一、题目详情

输入解释

  • 第一行输入三个正整数,N、P、r,N为树中的元素个数,P为树根处的货物价格,r为每走一层货物价格的上涨比率r%(变为父节点价格的(1+r%)倍)
  • 下面1行依次输入1~N号结点的父节点编号(根节点则输入-1)

输出解释

输出两个数字,以空格分隔,分别是:能得到的最大价格(精度为两位小数) 具有最大价格的节点个数

思路

  1. 将供销商问题抽象成树,因为题中说可以保证每一个节点都只有一个供应来源,并且供应链中没有环,所以这个抽象过程应该还是挺明显的~
  2. 要理解求最大价格实际就是求树的深度,一般用DFS来获取树的最大深度,那么写dfs函数时就需要把当前深度作为一个参数,还需要将下标作为一个参数。函数形式为DFS(int index,int depth)。
  3. 递归边界是到达叶节点,也就是子节点数为0,每次都需要进行判断。
  4. 递归式是通过访问该节点的每一个子节点,同时当前深度加一。
  5. 在本题中树的结构比较简单,不涉及到权重等,只需要记录节点编号这一信息,所以不妨开一个vector型数组,以节点编号作为下标,用vector来存放每一个节点的子节点编号。

二、实现代码

算法笔记中用了DFS

#include<iostream>
#include<vector>
#include<math.h>
using namespace std;
const int maxn = 10005;
vector<int> child[maxn];
int maxdepth;  //最大深度
int n;
double p,r;
int num;  //深度为最大的节点个数
void DFS(int index,int depth)
{
	//递归边界
    if(child[index].size()==0)  //到达叶节点
    {
        if(depth>maxdepth)  //如果当前深度大于最大深度,则更新最大深度,并将num置1
        {
            maxdepth=depth;
            num=1;
        }
         //当前深度等于最大深度,则深度最大的节点个数++
        else if(depth==maxdepth) num++;  
        //记得是else if而不是if!!因为上一步设置了maxdepth=depth,写为if的话会执行num++

        return ;
    }
    
    for(int i=0;i<child[index].size();i++)
    {
        DFS(child[index][i],depth+1);  //递归式
    }
    
}
int main()
{
    int root,t;
    scanf("%d%lf%lf",&n,&p,&r);
    r /= 100;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&t);
        if(t!=-1) child[t].push_back(i);
        else root = i;
    }
    DFS(root,0);
    printf("%.2f %d",p*pow((1+r),maxdepth),num);
}

BFS实现

#include<iostream>
#include<vector>
#include<queue>
#include<math.h>
using namespace std;
const int maxn = 100005;
vector<int> child[maxn];
int d[maxn];  //d[i]为每个节点的深度
int maxdepth;
int n;
double p,r;
int num=0;
int main()
{
    int root,t;
    scanf("%d%lf%lf",&n,&p,&r);
    r /= 100;
    for(int i=0;i<n;i++)
    {
        scanf("%d",&t);
        if(t!=-1) child[t].push_back(i);
        else root = i;
    }
    queue <int> q;
    q.push(root);
    while(!q.empty())
    {
        t = q.front();
        q.pop();
        for(int i=0;i<child[t].size();i++)
        {
            d[child[t][i]] = d[t]+1;
            if(maxdepth<d[child[t][i]])   //更新操作
                maxdepth = d[child[t][i]];  
            q.push(child[t][i]);
        }
    }
    
    //已经得到最大深度maxdepth,通过遍历d数组来找出节点为maxdepth的节点个数
    for(int i=0;i<n;i++)
        if(d[i]==maxdepth) num++;  
        
    printf("%.2f %d",p*pow((1+r),maxdepth),num);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值