548 – TreeTime limit: 3.000 seconds |
Tree |
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
1 2 3 4 5 6 |
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
1 2 3 |
1 3 255 |
Miguel A. Revilla
1999-01-11
给出同一颗树的中序遍历和后序遍历, 树中每一个节点的值都唯一, 然后求最短路径的叶子, 如果有多条最短路径的话就输出最小的叶子.
这里就直接DFS, 然后遍历到了叶子过后就比较路径或者叶子大小.
在已知中序和后序遍历的时候, 如下:
中序 D B G E A C F
后序 D G E B F C A
有以下的特点, 首先后序遍历最后一个节点A必然是树的根节点, 然后在中序遍历中, A的左边必然是A左边子树, 右边必然是右边子树.
然后A在后续遍历中左边第一个节点必然是A的右儿子.
那么如何确定左儿子呢?
后序遍历中根永远是最后一个访问, 所以A在后续遍历中前面的要么是左边子树, 要么是右边子树, 由中序遍历可知D G B E在A的左边, F C在A的右边, 在后续遍历中最靠近A的左边子树成员即是A的左儿子, 然后还可以发现A的左边子树和右边子树在后续遍历中不会交叉, 所以如果知道A的子树节点个数的话就可以直接求出左儿子.
虽然卡了三天的WA, 但是最终还是好好巩固了一下树的遍历, anyway, failure is also processing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/******************************************************** * File Name: uvaoj548.cpp * Author: razrLeLe * Mail: razrlele@outlook.com * Homepage: https://yueyu.io * Created Time: Tue 30 Dec 2014 03:45:48 PM CST ******************************************************/ #include "vector" #include "set" #include "deque" #include "queue" #include "algorithm" #include "functional" #include "iostream" #include "cstdio" #include "cmath" #include "cstdlib" #include "string" #include "cstring" #include "string.h" #include "map" #include "cctype" #include "list" #include "stack" using namespace std; #define INF 0x3f3f3f3f #define LOCAL const int maxn = 10010; int num; int inorder[maxn], postorder[maxn]; bool visit[maxn]; struct bestRoute { int leafsize; int pathsize; }ans; bool ScanTree(int begin, int end, int boundary, int root, int sum) //search from inordertable { if(begin > end) return false; sum += postorder[root]; int p = begin; while(inorder[p] != postorder[root]) p++; int cnt = p-begin; bool right, left; left = ScanTree(begin, p-1, boundary, boundary+cnt-1, sum); right = ScanTree(p+1, end, boundary+cnt, root-1, sum); if(!right && !left) { if(sum < ans.pathsize) { ans.leafsize = postorder[root]; ans.pathsize = sum; } else if(sum == ans.pathsize && ans.leafsize > postorder[root]) { ans.leafsize = postorder[root]; } } return true; } int main() { #ifdef LOCAL freopen("/home/razrlele/build/data.txt", "r", stdin); freopen("/home/razrlele/build/out.txt", "w", stdout); #endif num = 0; while(~scanf("%d",&inorder[num++])) { ans.leafsize = maxn; ans.pathsize = maxn*maxn; while(getchar() != '\n') { scanf("%d", &inorder[num++]); } num = 0; scanf("%d", &postorder[num++]); while(getchar() != '\n') { scanf("%d", &postorder[num++]); } ScanTree( 0, num-1, 0, num-1, 0); printf("%d\n", ans.leafsize); num = 0; } return 0; } /* * 9 3 6 8 4 * 9 3 8 4 6 */ |