二叉树 UVA 548 Tree

题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19105

题意:

给定一棵树的后序排列和中序排列,求这棵树最小路径的叶节点的值

思路:

主要通过此题掌握什么是后序排列和中序排列,并且怎么用他们还原一棵树。

后序排列即先排左子树,再排右子树,最后排根节点。这样就决定了最后一个点为根节点。

中序排列即先排左子树,再排根节点,最后排右子树。这样就决定了根节点的左边和右边分别为左子数和右子树。

通过后序确定根节点,在中序中找到它划分为左右子树,递归实现重构树。

出错点主要是重构树的递归过程中左右子树的下标问题,WA一两次就出来啦。

当然打印出来的PDF和原题的数据范围不同导致要使用long long也是一个出错点。

源码:

#include <cstdio>

#include <cmath>

#include <cstring>

#include <string>

#include <algorithm>

#include <iostream>

using namespace std;

#define gmin(a,b) a<b?a:b

typedef long long ll;

const int MAXN = 10000+5;

char data[5*MAXN + 5];

int lv[MAXN],ji[MAXN];

int lson[MAXN],rson[MAXN];///depend on lv's standard

int ans;

ll res;

void solve(int mark,int st,int en,ll val)

{

    if(st == en){

//        printf("val = %d,ans = %d,st = %d,lv = %d\n",val+lv[st],ans,st,lv[st]);

        if(res > val+lv[st]){

            res = val + lv[st];

            ans = lv[st];

        }

        return;

    }

    for(int i=st; i<=en ;i++){

        if(lv[i] == ji[mark]){

            if(i != en){

                rson[i] = ji[mark-1];

                solve(mark-1,i+1,en,val+lv[i]);

            }

            if(i != st){

                lson[i] = ji[mark-(en-i)-1];

                solve(mark-(en-i)-1,st,i-1,val+lv[i]);

            }

        }

    }

}

int main()

{

    while(gets(data) != NULL){

        int len = strlen(data);

        int cnt = 0;

        int temp = 0;

        for(int i=0; i<len; i++){

            if(data[i] == ' '){

                lv[cnt++] = temp;

                temp = 0;

            }

            else if(data[i] >= '0' && data[i] <='9')

                temp = temp*10 + data[i] - '0';

        }

        lv[cnt++] = temp;

        temp = 0;

        gets(data);

        cnt = 0;

        len = strlen(data);

        for(int i=0; i<len; i++){

            if(data[i] == ' '){

                ji[cnt++] = temp;

                temp = 0;

            }

            else if(data[i] >= '0' || data[i] <= '9') temp = temp*10 + data[i] - '0';

        }

        ji[cnt++] = temp;

        memset(lson, -1, sizeof(lson));

        memset(rson, -1, sizeof(rson));

        res = MAXN*MAXN;

        solve(cnt-1,0,cnt-1,0);

//        for(int i=0; i<cnt; i++){

//            if(lson[i] == -1 && rson[i] == -1){

//                printf("leaf is %d\n",lv[i]);

//                ans = gmin(ans, lv[i]);

//            }

//        }

//        for(int i=0; i<cnt; i++)

//            printf("for %d,lson is %d,rson is %d\n",lv[i],lson[i],rson[i]);

        printf("%d\n",ans);

     }

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值