zoukankan      html  css  js  c++  java
  • UVa 548 Tree(中序遍历+后序遍历)

    给一棵点带权(权值各不相同,都是小于10000的正整数)的二叉树的中序和后序遍历,找一个叶子使得它到根的路径上的权和最小。如果有多解,该叶子本身的权应尽量小。输入中每两行表示一棵树,其中第一行为中序遍历,第二行为后序遍历。


    样例输入:
    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
    样例输出:
    1
    3
    255

    知识点:由中序遍历和后序遍历构建二叉树(中序遍历加上其余两种遍历中任意一种,都可以还原二叉树),因为后序遍历的最后一个字符就是根(前序遍历的第一个字符是根),然后再到中序遍历中找到根,就可以知道其左右子树的中序和后序遍历,然后递归,代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    #define fast                                ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    #define ll                                  long long
    #define _for(i,a,b)                         for(int i = a;i < b;i++)
    #define rep(i,a,b)                          for(int i = a;i <= b;i++)
    #define all(s)                              s.begin(), s.end()
    
    const int maxn = 1e9;
    const int maxv = 10000 + 10;
    int in_order[maxv], post_order[maxv], lch[maxv], rch[maxv];
    int n;
    
    bool read_list(int* a)//读取中序遍历和后序遍历
    {
    	string line;
    	if (!getline(cin, line)) return false;
    	stringstream ss(line);
    	n = 0;
    	int x;
    	while (ss >> x)a[n++] = x;
    	return n > 0;
    }
    
    //in_order[l1..r1]和post_order[l2..r2]建成二叉树,返回树根
    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 cnt = p - l1;//左子树的结点个数
    	lch[root] = build(l1, p - 1, l2, l2 + cnt - 1);//构建左子树
    	rch[root] = build(p + 1, r1, l2 + cnt, r2 - 1);//构建右子树
    	return root;
    }
    
    int best, bestsum;//目前为止的最优解和对应的权和
    
    void dfs(int u, int sum)
    {
    	sum += u;
    	if (!lch[u] && !rch[u]) //叶子(无左子树和右子树)
    	{
    		if (sum < bestsum || (sum == bestsum && u < best))
    		{
    			best = u;
    			bestsum = sum;
    		}
    	}
    	if (lch[u])dfs(lch[u], sum);
    	if (rch[u])dfs(rch[u], sum);
    }
    
    int main()
    {
    	while (read_list(in_order))
    	{
    		read_list(post_order);
    		build(0, n - 1, 0, n - 1);
    		bestsum = maxn;
    		dfs(post_order[n - 1], 0);
    		printf("%d
    ", best);
    	}
    	return 0;
    }
  • 相关阅读:
    ASP.NET : 自定义HttpModule的时候要注意的问题
    ASP.NET : Win7 及 IIS 7中对于处理程序映射
    .NET : 一定不要忘记关闭DataReader对象
    IE 8 Accelerator加速器开发介绍{转载}
    .NET : CLR Profiler的使用
    .NET : 在实现WCF的双工服务时可能遇到的问题
    Silverlight学习资源
    .NET : 如何查看值类型的大小
    .NET: 如何通过AppDomain动态加载插件程序
    Web.config中的特殊字符
  • 原文地址:https://www.cnblogs.com/theory/p/11884333.html
Copyright © 2011-2022 走看看