uva548解题报告

来源:互联网 发布:在线网络信托基金公司 编辑:程序博客网 时间:2024/06/05 23:43

简单描述下原题意,题目给出二叉树按照中序遍历和后序遍历得到的序列, 需要求出从根节点到叶子节点最短路径的叶子的权重。(其实也是它的编号)。如果存在多个解,则选择权重最小的那个。

解题思路: 1.需要解决一个问题:如何根据二叉树的中序遍历和后序遍历还原二叉树。 方法挺简单的,根据它们的各自定义可知,后序遍历中的最后一个数就是根节点值。然后在中序遍历中找到此值,它的左边为左子树,右边为右子树。然后递归求解。 同样的 如果知道二叉树的前序遍历和中序遍历又该如何还原二叉树呢?(中序遍历必须已知,否则二叉树不唯一。想想为什么?)。相仿,先序遍历中第一个值就是根节点。还原二叉树方法同上。

2. 如何求解权重和最小路径。这个只需要进行一次先序遍历,求出根节点到叶子节点所有的解。然后与最优解进行比较即可以得到。


ac代码如下:

#include <iostream>#include <sstream>using namespace std;const int MAXN = 100000;int in_order[MAXN], post_order[MAXN], lef[MAXN], righ[MAXN];int NCNT =0; // 存放输入的数据的个数 // 返回根节点 int build(int l1, int r1, int l2, int r2) {if (l1> r1) return 0;  int root = post_order[r2];int p = l1;while (in_order[p] != root)p++; int rCnt = r1 - p;// 计算右子树的个数 int lCnt = p - l1; // 左子树个数lef[root] = build(l1, l1+lCnt-1, l2, l2+ lCnt-1);righ[root]  = build(p+1, r1, l2+lCnt, r2-1); // 要少去最后一个(根) return root;} bool read_list(int *pArr) {string line;if (!getline(cin, line))return false;stringstream ss(line);int x;NCNT = 0;while (ss>>x)pArr[NCNT++] = x;return NCNT>0;}// ans为最佳的节点的权重 ans_sum为最佳路径权重和 int ans, ans_sum =100000;// 采用先序遍历获取结果 void dfs(int index, int sum) {sum += index;if (!lef[index] && !righ[index]) {// 此时为叶子节点if (sum < ans_sum || (sum == ans_sum && index < ans))  {ans = index;ans_sum = sum;}}if (lef[index])dfs(lef[index], sum);if (righ[index])dfs(righ[index], sum);}int main() {while (read_list(in_order)) {read_list(post_order);build(0, NCNT-1, 0, NCNT -1);ans_sum = 100000; // 假设为无穷大dfs(post_order[NCNT-1], 0); cout<< ans<<endl;}return 0;}


0 0
原创粉丝点击