UVa 548 - Tree

//method 1:步骤1:根据inorder,postorder建立二叉树 (必须动态生成数组,节点数<10000)
//动态生成数组3种方法:a)malloc分配节点
//b)建立一个node节点数组,手工分配节点 , 通过指针访问节点
//c)生成3个数组key[], node_left[], node_left[],通过数组下标索引访问节点
//步骤2:深度遍历(dfs)获得最小路径值及对应叶子节点
//AC:0.105s

//mehtod 2: 直接根据inorder, postorder来获取最小路径值及对应叶子节点
//AC:0.092s
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;

const int MAX = 10000;
int in[MAX];
int post[MAX];
int n;
const int MAX_INT = (unsigned int)(1<<31) - 1;

//method 1
/*
//node
int node[MAX], node_left[MAX], node_right[MAX];
int visit[MAX];
int cur = 0;

int get_node()
{
    node_left[cur] = node_right[cur] = 0;
    return cur++;
}

int build_tree(int *in, int *post, int n)
{
    if(n == 0) return 0;
    int root = get_node();
    int val = post[n-1];
    node[root] = val;
    if(n > 1) {
        int i;
        for(i=0; i<n; i++) {
            if(in[i] == val) break;
        }
        node_left[root] = build_tree(in, post, i);
        node_right[root] = build_tree(&in[i+1], &post[i], n-1-i);
    }
    return root;
}

void pre_order(int root)
{
    printf("%d ", node[root]);
    if(node_left[root]) pre_order(node_left[root]);
    if(node_right[root]) pre_order(node_right[root]);
}

int st[MAX];

void dfs(int root)
{
    int top = 0;
    int sum=0, m=MAX_INT, leaf;
    st[top++] = root;
    while(top > 0) {
        root = st[top-1];
        if(!visit[root]) sum += node[root];
        visit[root] = 1;
        if(!node_left[root] && !node_right[root]) {
            if(sum < m) { m = sum; leaf = node[root];}
            else if(sum == m) leaf = node[root];
        } else {
            if(!visit[node_left[root]]) {
                st[top++] = node_left[root];
                continue;
            } else if(!visit[node_right[root]]){
                st[top++] = node_right[root];
                continue;
            }
        }
        top--;
        sum -= node[root];
    }
    printf("%d\n", leaf);
}
*/

//method 2
int min_value;
int leaf;
void direct_search(int *in, int *post, int n, int path_value)
{
    int val = post[n-1];
    path_value += val;
    if(n > 1) {
        int i;
        for(i=0; i<n; i++) {
            if(in[i] == val) break;
        }
        if(i>0) direct_search(in, post, i, path_value);
        if(n-1-i>0) direct_search(&in[i+1], &post[i], n-1-i, path_value);
    } else { //leaf
        if(path_value < min_value) {
            min_value = path_value;
            leaf = val;
        } else if(path_value == min_value) {
            leaf = val;
        }
    }
}

int main ()
{
   #ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    #endif
    char c;
    for(n = 0; scanf("%d%c", &in[n++], &c) == 2;) {

        if(c == '\n') {
            for(int i=0; i<n; i++) {
                scanf("%d", &post[i]);
            }

            //method 1: 建设,搜索
            /*
            cur = 0;
            int root = build_tree(in, post, n);
            memset(visit, 0, sizeof(visit));
            dfs(root);
            */
            //method 2: 直接搜索
            min_value = MAX_INT;
            direct_search(in, post, n, 0);
            printf("%d\n", leaf);

            n = 0;
        }
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值