UVA - 548 Tree(二叉树的递归遍历)

题意:已知中序后序序列,求一个叶子到根路径上权和最小,如果多解,则叶子权值尽量小。

分析:已知中序后序建树,再dfs求从根到各叶子的权和比较大小

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1};
const int dc[] = {-1, 1, 0, 0};
const double pi = acos(-1.0);
const double eps = 1e-8;
const int MAXN = 10000 + 10;
const int MAXT = 1000000 + 10;
using namespace std;
string a, b;
vector<int> in_order, post_order;
int leftchild[MAXN];
int rightchild[MAXN];
int anssum;
int ansv;
int build_tree(int L1, int R1, int L2, int R2){
    if(L1 > R1) return 0;
    int root = post_order[R2];
    int st = L1;
    while(in_order[st] != root) ++st;
    int cnt = st - L1;//一定要通过个数来控制取出来的中序后序序列的左右下标
    leftchild[root] = build_tree(L1, st - 1, L2, L2 + cnt - 1);//值为root的左孩子结点的值,第四个参数不能写成st-1,因为取出来的相对应的中序和后序序列不一定是下标对齐的
    rightchild[root] = build_tree(st + 1, R1, L2 + cnt, R2 - 1);
    return root;
}
void dfs(int root, int sum){
    sum += root;
    if(!leftchild[root] && !rightchild[root]){//叶子
        if(sum < anssum || (sum == anssum && root < ansv)){
            anssum = sum;
            ansv = root;
        }
    }
    if(leftchild[root]){
        dfs(leftchild[root], sum);
    }
    if(rightchild[root]){
        dfs(rightchild[root], sum);
    }
}
int main(){
    while(getline(cin, a)){
        in_order.clear();
        post_order.clear();
        memset(leftchild, 0, sizeof leftchild);
        memset(rightchild, 0, sizeof rightchild);
        stringstream s1(a);
        int x;
        while(s1 >> x){
            in_order.push_back(x);
        }
        getline(cin, b);
        stringstream s2(b);
        while(s2 >> x){
            post_order.push_back(x);
        }
        int len = in_order.size();
        build_tree(0, len - 1, 0, len - 1);
        int root = post_order[len - 1];
        anssum = INT_M_INF;
        ansv = INT_M_INF;
        dfs(root, 0);
        printf("%d\n", ansv);
    }
}

已知中序和后序可建树,建成后,可输出前序序列。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {0, 0, -1, 1};
const int dc[] = {-1, 1, 0, 0};
const double pi = acos(-1.0);
const double eps = 1e-8;
const int MAXN = 10000 + 10;
const int MAXT = 1000000 + 10;
using namespace std;
string a, b;
vector<int> in_order, post_order, pre_order;
int leftchild[MAXN];
int rightchild[MAXN];
int build_tree(int L1, int R1, int L2, int R2){
    if(L1 > R1) return 0;
    int root = post_order[R2];
    int st = L1;
    while(in_order[st] != root) ++st;
    int cnt = st - L1;//一定要通过个数来控制取出来的中序后序序列的左右下标
    leftchild[root] = build_tree(L1, st - 1, L2, L2 + cnt - 1);//值为root的左孩子结点的值,第四个参数不能写成st-1,因为取出来的相对应的中序和后序序列不一定是下标对齐的
    rightchild[root] = build_tree(st + 1, R1, L2 + cnt, R2 - 1);
    return root;
}
void dfs(int root){
    pre_order.push_back(root);
    if(leftchild[root]){
        dfs(leftchild[root]);
    }
    if(rightchild[root]){
        dfs(rightchild[root]);
    }
}
int main(){
    while(getline(cin, a)){
        in_order.clear();
        post_order.clear();
        pre_order.clear();
        memset(leftchild, 0, sizeof leftchild);
        memset(rightchild, 0, sizeof rightchild);
        stringstream s1(a);
        int x;
        while(s1 >> x){
            in_order.push_back(x);
        }
        getline(cin, b);
        stringstream s2(b);
        while(s2 >> x){
            post_order.push_back(x);
        }
        int len = in_order.size();
        build_tree(0, len - 1, 0, len - 1);
        int root = post_order[len - 1];
        dfs(root);
        for(int i = 0; i < len; ++i){
            if(i) printf(" ");
            printf("%d", pre_order[i]);
        }
        printf("\n");
    }
}
时间: 2024-08-24 05:05:50

UVA - 548 Tree(二叉树的递归遍历)的相关文章

UVA 548(二叉树重建与遍历)

J - Tree Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-05-16) Description  Tree  You are to determine the value of the leaf node in a given binary tree that is the ter

[2016-02-08][UVA][548][Tree]

UVA - 548 Tree Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description You are to determine the value of the leaf node in a given binary tree that is the terminal node of a path of least value from the root

UVA 699(二叉树建树与遍历)

M - The Falling Leaves Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Appoint description:  System Crawler  (2014-02-08) Description  The Falling Leaves  Each year, fall in the North Central region is accompanied

辛星算法教程第一节即二叉树的递归遍历

我们都知道,二叉树的递归遍历可以分为三种:前序遍历.中序遍历和后序遍历,其实这三种遍历方式大同小异,由于都是使用递归实现的,因此也比较简单. 首先是tree.h文件,代码如下: #ifndef TREE_H #define TREE_H #include <stdio.h> #include <malloc.h> #include <assert.h> typedef int ElemType; typedef struct Btree { ElemType val;

二叉树的递归遍历

#include<iostream> #include<stack> using namespace std; /*二叉树的前序遍历,按照 根节点->左孩子->右孩子 */ typedef struct node { char data; struct node *lchild,*rchild; }BinTree; void creatBinTree(BinTree * &root){ char ch; if(ch=getchar()){ if(ch=='#')

二叉树的递归遍历和非递归遍历(附详细例子)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

UVa 548 (二叉树的递归遍历) Tree

题意: 给出一棵由中序遍历和后序遍历确定的点带权的二叉树.然后找出一个根节点到叶子节点权值之和最小(如果相等选叶子节点权值最小的),输出最佳方案的叶子节点的权值. 二叉树有三种递归的遍历方式: 先序遍历,先父节点  然后左孩子  最后右孩子 中序遍历,先左孩子  然后父节点  最后父节点 后序遍历,先左孩子  然后右孩子  最后父节点 这里有更详细的解释: http://blog.csdn.net/sicofield/article/details/9066987 紫书上面写错了,后序遍历最后一

Tree UVA - 548 已知中序遍历和后序遍历,求这颗二叉树。

You are to determine the value of the leaf node in a given binary tree that is the terminal node of a path of least value from the root of the binary tree to any leaf. The value of a path is the sum of values of nodes along that path. Input The input

二叉树的递归遍历 Tree UVa548

题意:给一棵点带权的二叉树的中序和后序遍历,找一个叶子使得他到根的路径上的权值的和最小,如果多解,那该叶子本身的权值应该最小 解题思路:1.用getline()输入整行字符,然后用stringstream获得字符串中的数字 2.用数组in_oder[]和post_order[]分别表示中序遍历和后序遍历的顺序,用数组rch[]和lch[]分别表示结点的左子树和右子树 3.用递归的办法根据遍历的结果还原二叉树(后序遍历的最后一个树表示的是根节点,中序遍历的中间一个表示根节点) 4.二叉树构造完成后

二叉树的递归遍历 The Falling Leaves UVa 699

题意:对于每一棵树,每一个结点都有它的水平位置,左子结点在根节点的水平位置-1,右子节点在根节点的位置+1,从左至右输出每个水平位置的节点之和 解题思路:由于上题所示的遍历方式如同二叉树的前序遍历,与天平那题不同,本题不需要构造出完整的结点左右子树,只需要构造出结点的相对位置,每次输入一个结点树,若为-1,则返回,否则依次递归执行input(p-1)与input(p+1). 代码如下: 1 #include<stdio.h> 2 #include<cstring> 3 #inclu