树上搜索ccf csp第32次认证第三题

题目描述

树上搜索
ccf csp第32次认证第三题
原题链接:http://118.190.20.162/view.page?gpid=T178

样例

输入

5 2
10 50 10 10 20
1 1 3 3
5
3

输出

2 5
2 5 3 4

思路

本题是一道大模拟题,用到的算法不难但杂,稍不注意就会出错

解题关键

1.对于每一个类别,统计它和其全部后代类别的权重之和,同时统计其余全部类别的权重之和,并求二者差值的绝对值,选择绝对值最小的类别。这个条件直接做需要时刻维护每次迭代二者差值的绝对值,比较麻烦,于是转化为求每个节点及后代权重和的两倍与当前树总权重差的绝对值,当两者绝对值最小时就可以得到当前查询的节点。

2.不仅要记录当前节点的孩子节点,也到同时记录当前节点的父节点。前者用链表存,后者直接用数组存。

3.数据会爆int ,要开long long

题解

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 2010;

int idx,h[N],e[N],ne[N],w[N];
int fa[N];
int n,m;
LL u[N],uu[N];
bool st[N];
//st是表示每个节点的状态,st=true说明这个节点在树中,可以访问,st=false说明这个节点已经被删除,不能访问

void add(int a,int b){
    ne[idx]=h[a];
    e[idx]=b;
    h[a]=idx++;
}

LL dfs(int x){
    LL sum=w[x];
    for(int i=h[x];i!=-1;i=ne[i]){
        int j=e[i];
        uu[j]=dfs(j);
        sum+=uu[j];
    }
    return sum;
}


//返回当前节点最有可能被查询的那个节点
int query(int head,LL all){
    int temp=head;
    for(int i=h[head];i!=-1;i=ne[i]){
        int j=e[i];
        if(!st[j]) continue;
        int p=query(j,all); //找到它的子节点最有可能被查询的那个节点
        if(abs(u[p]*2-all)<abs(u[temp]*2-all)) temp=p;//差值更小,直接更新即可 
        else if(abs(u[p]*2-all)==abs(u[temp]*2-all)&&p<temp) temp=p;//差值一样,取编号更小的节点
    }
    return temp;
}


int main(){
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>w[i];
    }
    fa[1]=0;
    for(int i=2;i<=n;i++){
        int a;
        cin>>a;
        fa[i]=a;
        add(a,i);
    }
    uu[1]=dfs(1);
    while(m--){
        memset(st,true,sizeof st);
        memcpy(u,uu,sizeof uu);//每次迭代前利用uu重置u数组,典型的空间换时间
        int head=1;
        int x;
        cin>>x;//x是我们想要的那个节点
        while (1)
        {
            int t=query(head,u[head]);//t是现在要判断的节点 
		    bool fl=false;
			for(int i=h[head];i!=-1;i=ne[i]){
		        int j=e[i];
		        if(!st[j]) continue;
		        fl=true;
		    }
		    if(!fl) break;//当现在整个树只有一个节点时,退出循环
            cout<<t<<" ";
            bool flag=false;
            for(int i=x;i!=0;i=fa[i]){
                if(i==t) flag=true; //目标节点是否为当前节点的后代节点
            }
            if(flag){
                head=t;//如果是则头节点改成当前节点
            }
            else{
                st[t]=false;//如果不是那么一定在另一部分,头节点不变,但要把当前节点及其后代节
                //点从树中删除,只需要修改当前节点的状态即可,因为dfs查询的时候是从上往下查询
                //到,到不了父节点,自然也到不了它的子节点。
                for(int i=fa[t];i!=0;i=fa[i]){ 
                    u[i]-=u[t];//这个子树删除了,它的父节点的加权和也要修改
                }
            }
        }
        puts("");
    }
    return 0;
}

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CCF(中国计算机学会)CSP(中国软件专业人员认证)是国内一项重要的IT技术认证考试。CSP考试是由CCF组织和管理的,旨在评估考生在软件开发和项目管理领域的专业技能。 CSP认证涵盖了多个方面的知识,包括软件工程、项目管理、数据库管理、网络技术等。试通常分为选择和编程两部分,对考生的理论知识和实际应用能力进行综合测试。 CCF CCF CSP认证的难度适中,目涉及的知识点丰富。通过参加CSP考试,考生不仅可以提升自己的专业技能,还可以获得一个行业认可度较高的证书。 参加CSP考试有一定的门槛,要求考生具有一定的软件开发和项目管理经验。考生需要通过报名,参加线下考试,最终取得成绩。考试内容和难度每年可能会有所调整,考生需要及时了解最新的考试大纲和目要求,为考试做好充分准备。 对于有意参加CSP考试的人来说,可以通过查阅参考书籍、参加培训班、刷练习等方式来提高自己的知识和能力。此外,还可以参加相关的学术交流活动、讲座等,积极与其他从业人员交流,提高自己的专业水平。 CSP认证的通过对于求职者来说具有一定的参考价值,可以证明自己在软件开发和项目管理领域的专业水平。对于企业来说,CSP认证也是一种可靠的招聘参考,可以帮助企业筛选出具备一定技术能力的人才。 总之,CCF CSP认证是一个重要的IT技术认证考试,对于提升个人技术能力和求职竞争力具有一定的帮助。希望大家能够认真对待,做好充分准备,取得好的成绩。 ### 回答2: CCF(中国计算机学会)CSP(计算机软件专业技术资格认证)是中国计算机学会推出的一项专业认证考试。它旨在评估计算机软件专业人员的专业技术水平和能力。CSP认证CSP考试的重要组成部分。 CSP认证覆盖了计算机软件专业的各个领域,包括计算机系统基础、软件工程、算法与数据结构、程序设计语言、数据库、计算机网络等。试内容涵盖了理论知识和实际应用,旨在全面考核考生的综合能力。 CSP认证设置了多种型,包括选择、填空、编程等。选择考查考生对知识点的理解和记忆,填空考查考生对概念和原理的掌握,编程则考查考生的实际编程能力和解决问的能力。 CSP认证的难度逐级递增,旨在评估考生在计算机软件专业领域的深度和广度。考生需要通过对试的解答来展示自己的知识水平和能力。 参加CSP认证考试的考生可以通过自我学习、参加培训班等方式进行备考。在备考过程中,应重点掌握基础知识和常用技能,并通过解答CSP认证进行实践和巩固。 总之,CCF CSP认证是评估计算机软件专业人员能力的重要考核工具,通过备考和解答试,考生可以展示自己在该领域的技术水平和能力,取得CSP认证资格。 ### 回答3: CCF CSP认证是由中国计算机学会(CCF)推出的一项计算机相关的职业技术认证。该认证旨在评估考生在计算机科学与技术领域的理论知识和实际应用能力。通过参加并且通过CCF CSP认证,考生可以获得相应的认证证书,这将有助于他们在职业发展和工作找寻方面的竞争力。 CCF CSP认证包括多个专业领域,如算法设计与分析、计算机组成原理、数据库原理与应用、操作系统原理与应用、计算机网络等。试涵盖了计算机科学与技术的核心知识点和常见应用场景,以及对相关技术的理解和解决问的能力。 参加CCF CSP认证需要考生具备扎实的计算机基础知识,熟悉常见的编程语言和工具,具备一定的编程能力和计算机系统分析与设计的经验。在考试中,除了理论知识的掌握外,考生还需要具备解决实际问的能力,能够独立思考,分析和解决具体的计算机科学与技术问。 通过CCF CSP认证,考生可以证明自己在计算机领域的专业能力和知识水平,这对于求职或职业发展都具有积极的影响。同时,认证证书还能够作为考生在求职过程中的一个竞争优势,增加他们在相关职位的竞争力。 总之,CCF CSP认证是一个评估计算机科学与技术素养的标准化考试,通过参加该考试并获得认证证书,考生可以证明自己的专业能力和知识水平,这对于提升职业竞争力和求职成功都具有积极的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值