• 数据结构_Summary


    问题描述

    可怜的 Bibi 丢了好几台手机以后,看谁都像是小偷,他已经在小本本上记
    下了他认为的各个地点的小偷数量。
    现在我们将 Bibi 的家附近的地形抽象成一棵有根树。 每个地点都是树上的
    一个节点,节点上都标注了 Bibi 心中该地点的小偷数量。现在 Bibi 告诉你一个
    节点 k,请你求出以该节点为根的子树中小偷数量的总和,以及子树中小偷最多
    的节点的小偷数量。


    ★数据输入
    输入第一行为一个正整数 n1≤n≤100000) 表示树的节点数目,树根的编号
    总是为 1,且没有小偷。
    接下来 n-1 行, 每行两个正整数 px1≤x≤100)。 代表编号为 i 的节点的父
    亲节点 p 和该节点的小偷数量 x。 数据保证输入的 p 小于当前的 i。 这里的 i 2
    依次数到 n
    n+1 行一个整数 m1≤m≤n), 表示询问组数。
    n+2 行有 m 个整数,每个整数 ki1≤ki≤n) 代表该组询问中的节点 k


    ★数据输出
    输出 m 行, 每行两个整数,代表以询问节点为根的子树中小偷数量的总和,
    以及子树中小偷最多的节点的小偷数量。

    输入示例 输出示例
    3
    1 56
    1 82
    1 1
    138 82



    思路

      (1)这题可以用数来暴力做,用vector<>来存子节点的位置。

        因为vector每次满都在开双倍空间,可能会占用较多空间,在移动数据上也会消耗更多时间

        理论上因该是可行的,但是不知道是OJ使用vc6的原因还是vector开了过大空间,测试时有一个点RE

      (2)用结构体数组,存好数据够从右向左遍历,将值加到对应父节点上

     

    code

      (1)使用vector,一个RE(不知道怎么死的)

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    #include <vector>
    
    struct Node
    {
        Node():num(0),ans_sum(0),ans_max(0){}
        int num;
        int ans_sum;
        int ans_max;
        vector<int> child;    
    };
    
    Node *arr = NULL;
    
    int dfs(int index) // return sum of children
    {
        arr[index].ans_sum = arr[index].num;
        arr[index].ans_max = arr[index].num;
        if(arr[index].child.empty())
        {
            
        }
        else
        {
            int i,tmp;
            for(i=0;i<arr[index].child.size();i++)
            {
                arr[index].ans_sum += dfs(arr[index].child[i]);
                tmp = arr[arr[index].child[i]].ans_max;
                if(tmp>arr[index].ans_max) arr[index].ans_max = tmp;
            }
        }
        return arr[index].ans_sum;
    }
    
    int main()
    {
        int i,j;
        int n,p,x,m,k;
        scanf("%d",&n);
        arr = new Node[n+1];//should not use malloc
        for(i=2;i<=n;i++)
        {
            scanf("%d %d",&p,&x);
            arr[p].child.push_back(i);
            arr[i].num = x;
        }
        dfs(1);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d",&k);
            printf("%d %d
    ",arr[k].ans_sum,arr[k].ans_max);
        }
        
        delete[] arr;
        return 0;
    }

      (2)使用结构体数组,AC

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct Node
    {
        int sum;
        int max;
        int fa;//father 
    };
    
    int main()
    {
        int n;
        scanf("%d",&n);
        Node *p = (Node *)malloc(sizeof(Node)*(n+1));
        memset(p,0,sizeof(Node)*(n+1));
        //-----------------------------------------------
        int i,j,index;
        for(i=2;i<=n;i++)
        {
            scanf("%d %d",&p[i].fa,&p[i].sum);
            p[i].max = p[i].sum;
        }
        for(i=n;i>1;i--)
        {
            p[p[i].fa].sum+=p[i].sum;
            p[p[i].fa].max = p[i].max > p[p[i].fa].max ? p[i].max : p[p[i].fa].max;
        }
        scanf("%d",&j);
        for(i=1;i<=j;i++)
        {
            scanf("%d",&index);
            printf("%d %d
    ",p[index].sum,p[index].max);
        }
        //-----------------------------------------------
        free(p);
        return 0;
    }
  • 相关阅读:
    使用Azure进行自动化机器学习
    关于ML.NET v1.0 RC的发布说明
    关于ML.NET v0.8的发布说明
    使用ML.NET + Azure DevOps + Azure Container Instances打造机器学习生产化
    使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型
    neo4j 数据库迁移
    ubuntu1604 搜狗输入法安装
    Chrome 键盘快捷键
    Ubuntu Cleaner清理工具
    bash 数组
  • 原文地址:https://www.cnblogs.com/cbattle/p/7790381.html
Copyright © 2020-2023  润新知