【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%。

相关文章
|
4月前
|
算法
Hierholzer算法dfs找欧拉回路模板
Hierholzer算法dfs找欧拉回路模板
59 0
|
4月前
【每日一题Day305】LC1448统计二叉树中好节点的数目 | dfs
【每日一题Day305】LC1448统计二叉树中好节点的数目 | dfs
34 0
|
12月前
|
存储 C语言 C++
问题 D: DS查找—二叉树平衡因子(不一样的新做法哦)
问题 D: DS查找—二叉树平衡因子(不一样的新做法哦)
|
14天前
|
存储 C语言 C++
D : DS查找—二叉树平衡因子
这篇文章介绍了如何计算二叉树的平衡因子,并提供了C++代码实现,用于根据二叉树的数组存储形式,计算并输出每个节点的平衡因子。
|
4月前
|
存储 人工智能
贪心,DFS:小美的树上染色
贪心,DFS:小美的树上染色
44 1
|
4月前
|
算法
深度优先搜索(DFS)的基础理解与实现
深度优先搜索(DFS)的基础理解与实现
48 0
|
定位技术
DFS:迷宫解的方案数
DFS:迷宫解的方案数
<<算法很美>>——(七)——DFS典题(一):水洼数目
<<算法很美>>——(七)——DFS典题(一):水洼数目
<<算法很美>>——(七)——DFS典题(一):水洼数目
|
算法
【数据结构和算法】图的应用(最小生产树、最短路径、拓扑排序、关键路径)
【数据结构和算法】图的应用(最小生产树、最短路径、拓扑排序、关键路径)
252 0
【数据结构和算法】图的应用(最小生产树、最短路径、拓扑排序、关键路径)