UVa 548 Tree (建树+前序后序)

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 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 file will contain a description of the binary tree given as the inorder and postorder traversal
sequences of that tree. Your program will read two line (until end of file) from the input file. The first
line will contain the sequence of values associated with an inorder traversal of the tree and the second
line will contain the sequence of values associated with a postorder traversal of the tree. All values
will be different, greater than zero and less than 10000. You may assume that no binary tree will have
more than 10000 nodes or less than 1 node.
Output
For each tree description you should output the value of the leaf node of a path of least value. In the
case of multiple paths of least value you should pick the one with the least value on the terminal node.
Sample Input
3 2 1 4 5 7 6
3 1 2 5 6 7 4
7 8 11 3 5 16 12 18
8 3 11 7 16 18 12 5
255
255
Sample Output
13
255

题目的意思是给你一个树的中序和后序遍历的情况,让你找出从根节点走到叶子节点经过的节点的权值和最小,输出这条路径的叶子节点的权值,如果最小的路径有多种则输出权值最小的叶子节点。

这个题输入处理比较奇葩,网上找了一个模板,用来读入,然后就是普通的递归建树,最后再dfs就行了。

代码如下:

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4 #define M 100050
 5 #define inf 0x3f3f3f3f
 6 struct node
 7 {
 8     struct node *left;
 9     struct node *right;
10     int v;
11 };
12 node *root;
13 int in[M],post[M],top,min_sum,ans;
14 char s[M];
15 int find(int *a,int n,int c)
16 {
17     for (int i=n-1;i>=0;i--)
18     if (a[i]==c)
19     return i;
20     return 0;
21 }
22 node *build(int n,int *in,int *post)
23 {
24     if (n<=0)
25     return NULL;
26     int p=find(in,n,post[n-1]);
27     node *root=(node *)malloc(sizeof(node));//将malloc(分配空间)的返回值强转成 node *型指针变量
28     root->v=post[n-1];
29     root->left=build(p,in,post);
30     root->right=build(n-p-1,in+p+1,post+p);
31     return root;
32 }
33 void dfs (node *root,int sum)
34 {
35     if (root==NULL)
36     return;
37     sum+=root->v;
38     if (root->left==NULL&&root->right==NULL)
39     {
40         if (min_sum>sum)
41         {
42             min_sum=sum;
43             ans=root->v;
44         }
45         else if (min_sum==sum)
46         ans=min(ans,root->v);
47         return ;
48     }
49     dfs(root->left,sum);
50     dfs(root->right,sum);
51 }
52 int init (char *s,int *a)
53 {
54     int top=0;
55     for (int i=0;s[i];++i)
56     {
57         while (s[i]==‘ ‘)
58         i++;
59         a[top]=0;
60         while (s[i]&&isdigit(s[i]))
61         {
62             a[top]=a[top]*10+s[i]-‘0‘;
63             ++i;
64         }
65         top++;
66         if (!s[i])
67         break;
68     }
69     return top;
70 }
71 int main()
72 {
73     //freopen("de.txt","r",stdin);
74     while (gets(s))
75     {
76         init(s,in);
77         gets(s);
78         top=init(s,post);
79         node *root;
80         root=build(top,in,post);
81         min_sum=inf;
82         ans=min_sum;
83         dfs(root,0);
84         printf("%d\n",ans);
85     }
86     return 0;
87 }
时间: 2024-08-07 07:18:20

UVa 548 Tree (建树+前序后序)的相关文章

UVa 548 Tree(建树,递归遍历)

题意  给你一个树的中序遍历和后序遍历  某个节点的权值为从根节点到该节点所经过节点的和  求权值最小的叶节点的值  如果存在多个  输出值最小的那个 把树建好就好说了  递归递归dfs msun保存最小叶节点权值  ans保存答案 #include<cstdio> #include<cctype> #include<cstring> using namespace std; const int maxn = 10005, INF = 0x3f3f3f3f; int i

[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

通过前序(后序)+中序创建树

通过二叉树的前序遍历和中序遍历创建树 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct NODE { int nValue; struct NODE* pLeft; struct NODE* pRight; }BinaryTree; int Getxb(char* inorder,int num) { //得到根在中序遍历中的下标 for(int i=0;i<strlen(

根据前序/后序遍历和中序遍历序列建树

根据前序遍历和中序遍历序列建树: 1 // 先序序列pre[preL,preR],中序序列in[inL,inR] 2 node* BuildTree(int preL,int preR,int inL,int inR){ 3 if(preL>preR){ 4 return NULL; 5 } 6 node *root=new node; 7 root->data=pre[preL]; 8 int k; 9 for(k=inL;in[k]!=pre[preL];k++){ 10 ; 11 } 1

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

题意:已知中序后序序列,求一个叶子到根路径上权和最小,如果多解,则叶子权值尽量小. 分析:已知中序后序建树,再dfs求从根到各叶子的权和比较大小 #include<cstdio> #include<cstring> #include<cstdlib> #include<cctype> #include<cmath> #include<iostream> #include<sstream> #include<itera

UVa 548 Tree【二叉树的递归遍历】

题意:给出一颗点带权的二叉树的中序和后序遍历,找一个叶子使得它到根的路径上的权和最小. 学习的紫书:先将这一棵二叉树建立出来,然后搜索一次找出这样的叶子结点 虽然紫书的思路很清晰= =可是理解起来好困难啊啊啊啊 后来终于问懂一丢丢了--- 比如说样例: 中序遍历:3 2 1 4 5 7 6 后序遍历:3 1 2 5 6 7 4 首先做第一层: 在后序遍历中的最后一个数为根节点,然后在到中序遍历中找到这个根节点,在这个根节点的左边是左子树,右边是右子树,这样就确定出了左子树和右子树的区间 然后做第

Uva 548 Tree

0.这是一道利用中序遍历和后序遍历确定二叉树的题目,学会建树 关键点理解这段代码 int build(int L1,int R1,int L2,int R2) { //printf("built:\n"); if(L1>R1) return 0;//空树 int root=post_order[R2]; int p=L1; while(in_order[p] != root) p++; int cnt = p-L1;//左子树的结点个数 lch[root]=build(L1,p-

51nod 1832 前序后序遍历

思路:设只有一颗子树的节点有ans个设前序边历数组为pre[100],后序遍历数组为pos[100]:前序遍历的第二个元素是A的一个子节点左右节点不知,设ax-ay表示一个树的前序遍历,bx-by表示后序遍历,可知如果pre[ax+1] = pos[i] 且 i = by-1,上一个根节点只有一个子树,此时令计数变量ans++:如果i != b2-1,很明显存在左右子树,此时应分别处理此时左子树为的前后序边历分别为:ax+1~ax+1+i-bx,bx~i,右子树为:ax+1+i-bx~ay,i+

[Leetcode 105]*前序后序遍历形成树

public TreeNode find(int[] preorder, int[] inorder,int j, int start, int end) { if (j > preorder.length - 1 || start > end) { return null; } TreeNode root = new TreeNode(preorder[j]); int flag = 0; for (int i = start; i <= end; i++) { if (inorder