【1079】&【1090】供应树DFS

简介: 懂题目的输入,每行开头为当前结点i的叶子结点个数,若该首数字非0,则该行后面的数字都为i结点的叶子结点数组下标(也就是题目直接给出结点的编号,且结点的编号一定是0、1、…N-1,N为结点个数——不需要newNode函数,因为题目中给定的编号可以直接作为Node数组的下标使用);而若该首数字为0,则该行

【1079】Total Sales of Supply Chain (25 分)

1.题目

https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560

给出一棵树,求出叶子结点“带权路径”之和,这里不是以前那种带权,叶子结点真正的权值由该结点的深度决定(幂次方)——根结点处货物的价格为P,叶子结点的括号内数字表示货物数。

看懂题目的输入,每行开头为当前结点i的叶子结点个数,若该首数字非0,则该行后面的数字都为i结点的叶子结点数组下标(也就是题目直接给出结点的编号,且结点的编号一定是0、1、…N-1,N为结点个数——不需要newNode函数,因为题目中给定的编号可以直接作为Node数组的下标使用);而若该首数字为0,则该行后面的数字为叶结点的权值。

2.思路

DFS就对了,注意这题根结点的深度应设为0。

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);
  }
}

3.完整代码

#include<vector>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
using namespace std;
const int maxn=100010;
double ans=0,rate;
struct node{
  double data;
  vector<int> child;
}Node[maxn];
void DFS(int index,int depth){
  if(Node[index].child.size()==0){
    ans+=Node[index].data*pow(1+rate,depth);
    return;
  }
  for(int i=0;i<Node[index].child.size();i++){
    DFS(Node[index].child[i],depth+1);//递归访问子结点
  }
}
int main(){
  int n;
  int num;
  double price;
  scanf("%d%lf%lf",&n,&price,&rate);
  rate/=100;
  for(int i=0;i<n;i++){
    scanf("%d",&num);
    if(num==0){
      scanf("%lf",&Node[i].data);
    }else{
      for(int j=0;j<num;j++){
        //scanf("%d",&Node[i].child[j]);
        int child;
        scanf("%d",&child);
        Node[i].child.push_back(child);
      }
    }
  }
  DFS(0,0);
  printf("%.1f\n",price*ans);
  system("pause");
}

4.注意

(1)一开始OJ提示答案错误,后来发现是定义了全局变量rate后,还在main函数里面重复定义了rate局部变量。

(2)注意scanf("%d",&Node[i].child[j])这样写不对。

(3)题目给定的rate是百分数,因此要除以100,如样例的rate=1.00指1%。

【1090】Highest Price in Supply Chain (25 分)

1.题目

https://pintia.cn/problem-sets/994805342720868352/problems/994805376476626944

2.思路

和上一题类似,区别是这个要求所有叶结点中的最高价格(每层的货物价格会在父结点的价格上增加r%)和这个价格的叶结点总个数,也即【1090】的叶子结点的“初始”点权值是相同的,即只要计算深度最深的结点。

由于不用考虑结点的点权,可以不用设结构体结点了,而直接用vector<int>child[MAXV]替代,每个child[i]都是一个vector,存放各个结点的所有子结点下标。

3.完整代码

#include<vector>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
using namespace std;
const int maxn=100010;
int num=0;//最大深度的结点个数
vector<int>child[maxn];
int maxdepth=0;
double ans;
double rate,price;
void DFS(int index,int depth){
  if(child[index].size()==0){
    if(depth>maxdepth){//递归边界:到达叶结点
      maxdepth=depth;
      ans=price*pow(1+rate,maxdepth);
      //printf("%lf\n",price);
      num=1;//重置最大深度的结点个数为1
    }else if(depth==maxdepth){
      num++;
      ans=price*pow(1+rate,maxdepth);//别漏了这句
    }
    return;
  }
  for(int i=0;i<child[index].size();i++){//注意判断的下标不是i
    DFS(child[index][i],depth+1);
  }
}
int main(){
  int n,father,root;
  scanf("%d%lf%lf",&n,&price,&rate);
  rate/=100;
  for(int i=0;i<n;i++){
    scanf("%d",&father);
    if(father!=-1)
      //child[father][i]=i;
      child[father].push_back(i);//i是father的子结点
    else
      root=i;
  }
  DFS(root,0);
  printf("%.2f %d\n",ans,num);
  system("pause");
}

4.注意

(1)根结点显然没有父结点,所以输入的第二行中遇到-1时的i即为root。

(2)题目给定的rate是百分数,因此要除以100,如样例的rate=1.00指1%。

相关文章
|
25天前
|
供应链 算法 存储
数据结构之货仓选址问题(DFS)
货仓选址问题是供应链管理中的关键挑战,直接影响物流效率和成本。本文介绍了一种基于深度优先搜索(DFS)算法的解决方案,通过计算不同位置的总距离,找到使总距离最小的最优货仓位置。此方法适用于小规模数据集,易于理解与实现,但随数据量增大,效率显著下降。示例代码展示了如何利用DFS算法计算最小总距离,并提供了完整的实现流程。
51 0
数据结构之货仓选址问题(DFS)
|
7月前
|
存储 人工智能
贪心,DFS:小美的树上染色
贪心,DFS:小美的树上染色
77 1
|
7月前
|
人工智能 算法 BI
【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目
【深度优先搜索】【树】【图论】2973. 树中每个节点放置的金币数目
L2-026 小字辈(树的建立+BFS)
L2-026 小字辈(树的建立+BFS)
82 0
|
7月前
|
算法
【每日一题Day235】LC1483树节点的第 K 个祖先 | 倍增
【每日一题Day235】LC1483树节点的第 K 个祖先 | 倍增
52 1
|
数据安全/隐私保护
列出叶节点 (二叉树的建立和BFS)
列出叶节点 (二叉树的建立和BFS)
94 0
<<算法很美>>——(七)——DFS典题(一):水洼数目
<<算法很美>>——(七)——DFS典题(一):水洼数目
<<算法很美>>——(七)——DFS典题(一):水洼数目
|
测试技术
#### [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/)
#### [623. 在二叉树中增加一行](https://leetcode.cn/problems/add-one-row-to-tree/)