|邻接表+dfs(index,depth)|1090 Highest Price in Supply Chain|1079| Total Sales of Supply Chain||功夫达人

在这里插入图片描述这道题莫名的让我想到了“功夫达人”那道题,
也是一样的用邻接表+dfs(index,depth),
但是不知道为什么这道题不用标记visited[]数组

通过深度优先搜索计算出最长的供应链,
再定义一个计数器计算出这个供应链的个数

求所有叶子节点中的最高价格和这个价格的叶子节点的个数
也就是求最深层次的叶子节点

//销售供应的树代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

int n,root,maxDepth=0,num;
double p,r;
vector<int> child[100010];

void dfs(int index,int depth){
    
    
    if(child[index].size()==0){
    
    //没有孩子,到达根节点了
        if(depth>maxDepth){
    
    
            maxDepth=depth;
            num=1;
        }else if(depth==maxDepth){
    
    
            num++;
        }
        return;
    }
    for(int i=0;i<child[index].size();i++){
    
    
        dfs(child[index][i],depth+1);//递归访问节点index的子节点
    }
}

int main()
{
    
    
  scanf("%d %lf %lf",&n,&p,&r);
  for(int i=0;i<n;i++){
    
    
      int tmp;
      scanf("%d",&tmp);
      if(tmp==-1){
    
    
          root=i;
      }else{
    
    
          child[tmp].push_back(i);
      }
  }
  dfs(root,0);
  printf("%.2f %d",p*pow(1+0.01*r,maxDepth),num);//根节点为第0层  
  return 0;
}

在这里插入图片描述

//功夫达人的代码
//方便比较,你会惊奇的发现,这他妈就是和1079那个求带点权的根节点之和的题一毛一样,
//差别就是这边是缩小,那是每层变大,你只要改变符号就好了,并且将其整数输出,OK,就该两处地方
#include <iostream>
#include <cstdio>
#include <set>
#include <cmath>
#include <vector>
using namespace std;


//set<int>s_de;

struct node{
    
    
    int expand;
    vector<int> child;
}Node[100010];

int n;
double z,r,ans=0.0;

void dfs(int index,int depth){
    
    
    //编号是index的节点的孩子个数为0,也就是说这个是叶子节点,
    //是我们要的点,我们要求所有叶子节点的总和
    if(Node[index].child.size()==0){
    
    
        ans+=Node[index].expand*pow(1-0.01*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,&z,&r);
    for(int i=0;i<n;i++){
    
    
        int num_child;
        cin>>num_child;
        if(num_child==0){
    
    
            int m;
            cin>>m;
            //s_de.insert(i);
            Node[i].expand=m;
        }else{
    
    
            for(int j=0;j<num_child;j++){
    
    
                int id_child;
                cin>>id_child;
                Node[i].child.push_back(id_child);
            }
        }
    }
    dfs(0,0);
    int ans_int=int(z*ans);
    //printf("%d %f",ans_int,ans*z);//404 404.526474---->printf("%.0f",ans*z)会输出405,四舍五入,但是题目说取整数就可以
    printf("%d",ans_int);
    return 0;
}

在这里插入图片描述1079 Total Sales of Supply Chain (25分)
在A1090的基础上增加了“货物量”的设定—点权(重)
因此节点的结构体的设定要改为

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

求每个叶子节点的价格之和…点权

//如果Ki为0,则该节点是叶子节点,后面的数字就是该叶节点的货物量
//如果Ki不为0,则表示该节点是非叶子节点,Ki为其子节点的个数,后面的数字都是子节点编号
//根节点的深度应该设为0

//Starting from one root supplier, 
// and the root supplier's ID is 0);
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

struct node{
    
    
    double data;//数据域(点权...货物量)
    vector<int>child;//指针域
}Node[100010];//存放树

int n;
double p,r,ans=0.0;


void dfs(int index,int depth){
    
    //为什么你就知道0是根节点的编号
    if(Node[index].child.size()==0){
    
    //到达叶子节点
        ans+=Node[index].data*pow(1+0.01*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);
    for(int i=0;i<n;i++){
    
    
        int tmp;
        scanf("%d",&tmp);
        if(tmp==0){
    
    //叶子节点标志
            scanf("%lf",&Node[i].data);//叶节点的货物量
        }else{
    
    
            for(int j=0;j<tmp;j++){
    
    
                int child;
                scanf("%d",&child);
                Node[i].child.push_back(child);//child是节点i的子节点
            }
        }
    }
    dfs(0,0);//dfs入口
    printf("%.1f",p*ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;

struct node{
    
    
   int w; 
   vector<int>child;   
}Node[100010];

int n;
double p,r,ans=0.0;

void dfs(int index,int depth){
    
    
    if(Node[index].child.size()==0){
    
    //编号是index的节点没有孩子,是根节点,是我们要的点--计算所有根节点和
        ans+=Node[index].w*pow(1+0.01*r,depth);
        return;
    }
    for(int i=0;i<Node[index].child.size();i++){
    
    //有几个孩子,遍历几次//第0个孩子///1234
        dfs(Node[index].child[i],depth+1);
    }
}

int main()
{
    
    
    scanf("%d %lf %lf",&n,&p,&r);
    for(int i=0;i<n;i++){
    
    
        int num_child;
        cin>>num_child;
        if(num_child==0){
    
    
            int weight;
            cin>>weight;
            Node[i].w=weight;
        }else{
    
    
            for(int j=0;j<num_child;j++){
    
    
                int id_child;
                cin>>id_child;
                Node[i].child.push_back(id_child);
            }
        }
    }
    
    dfs(0,0);//0是根节点,是第0层
    printf("%.1f",ans*p);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44769957/article/details/109059924