ZOJ-#3516Tree of Three(dfs+vector)

        题目大意:给出一颗0为树根的树,每个结点均有一个权值,询问以结点为根的子结点中最大的三个值,若不够三个结点则返回-1.

        解题思路:因为是一颗树的形态,而要求子结点中的最大的三个值。因此最直观的想法就是从树的底部开始想根节点进行更新。这样进行更新遍历一次后,对各个结点的询问就可以直接给出。相应的做法是用vector来存储各个结点的父子关系,用dfs从底部开始向上进行遍历更新整个树,详见code。

        题目来源:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4381

       code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXN = 1e4+10;
int n,a,b,q,x;
int ans[MAXN][7];
vector<int> v[MAXN];

bool cmp(int a,int b){return a>b;}

void dfs(int x){
    while(!v[x].empty()){
        int p=v[x].back(); //获取x结点最后一个子结点
        v[x].pop_back(); //弹出该结点
        dfs(p); //继续迭代,直到树的叶子
        for(int i=3;i<6;++i) //接收儿子结点的值
            ans[x][i]=ans[p][i-3];
        sort(ans[x],ans[x]+6,cmp); //排序存储最大的
    }
}

int main(){
    //freopen("input.txt","r",stdin);
    while(~scanf("%d",&n)){
        memset(ans,-1,sizeof(ans)); //初始为无子结点
        scanf("%d",&ans[0][0]); //接收根结点
        for(int i=1;i<n;++i){
            scanf("%d%d",&a,&b);
            v[a].push_back(i); //存储父亲结点的子结点,邻接表
            ans[i][0]=b; //更新对应结点的权值
        }
        dfs(0); //进行由底向上地更新各个结点
        scanf("%d",&q);
        while(q--){
            scanf("%d",&x);
            if(ans[x][2]==-1) //如果子结点数量小于2,则返回-1
                printf("-1\n");
            else
                printf("%d %d %d\n",ans[x][0],ans[x][1],ans[x][2]);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值