UVA 548 Tree

本文介绍了解决UVA-548问题的方法,该问题要求通过给定的中序和后序遍历结果,找出从根节点到叶子节点路径和最小的叶子节点。文章详细解释了如何递归地划分左右子树,并使用深度优先搜索确定最终答案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UVA-548

题意:给出中序和后序,求路根到叶子节点径和最小的那个叶子节点。
解题思路:从后序中找到根节点,中序中根节点左边的是它的左子树,根节点右边的是它的右子树。然后不断处理,直到叶子节点两边无法再分,取最小的那个。
首先我们定义一个函数dfs(int now, int l, int r, int sum)。l,r是当前处理的范围是中序中的 l 到 r 这段树。now是当前是以后序中的第n个作为根节点。sum是到当前节点之前的路径和。
//map[i]表示后序中第i个的值,w[x]表示数字x在中序中的位置。
判断叶子节点:当l == r代表当前处理范围只有一个数,则就是叶子节点了。
左子树和右子树的now ,l , r 是多少?
首先对于右子树,它的now是now-1(后序遍历,如果存在右子树,右子树的根就是在它的前一个)。我们知道w[map[now]]的值,那么中序中 w[map[now]]+1 到 r 就是它的处理范围。
对于左子树,它的now应该是now扣除掉右子树中节点的个数,又知道右子树的范围,减一下就有来。左子树的处理范围 为l 到 w[map[now]]-1。

/*************************************************************************
    > File Name: UVA-548.cpp
    > Author: Narsh
    > 
    > Created Time: 2016年07月18日 星期一 15时30分43秒
 ************************************************************************/

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int map[110000],n,m,t,w[110000];
char c;
int ansum,ans;
void dfs(int now, int l, int r, int sum) {
    sum+=map[now];
//  if (map[now] == 0) return ;
    if (l > r) return ;
    if (l == r) {
        if (sum < ansum) {
            ansum=sum;
            ans=map[now];
        }
        return ;
    }
    dfs(now-1,w[map[now]]+1,r,sum);
    dfs(now-1-r+w[map[now]],l,w[map[now]]-1,sum);

}
int main() {
    while (scanf("%d%c",&t,&c) != EOF){
        n=1;w[t]=n;
        while (c !='\n') {
            scanf("%d%c",&t,&c);
            n++;
            w[t]=n;
        }
        for (int i = 1; i <= n; i++) {
            scanf("%d%c",&t,&c);
            map[i]=t;
        }
        int sum,r;
        ansum=999999999;
        dfs(n,1,n,sum);
        printf("%d\n",ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值