UVA548 Tree

 洛谷传送门

 题意

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

 题解

 首先在此回顾一下先序遍历、中序遍历、后序遍历的求法

 PreOrder(T)=T的根节点+PreOrder(T的左子树)+PreOrder(T的右子树)

 InOrder(T)=InOrder(T的左子树)+T的根节点+InOrder(T的右子树)

 PostOrder(T)=PostOrder(T的左子树)+PostOrder(T的右子树)+T的根节点

 我们不难发现可以利用后序遍历找到树根,再在中序遍历中找到树根,从而找出左右节点列表,然后递归构造左右子树

 树造好了,剩下的也就不用说了

 CODE

#include<bits/stdc++.h>
#define N 10010
using namespace std;
int ans,ansum,zx[N],hx[N],lc[N],rc[N],n;
bool read(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;
}
int build(int l,int r,int L,int R)
{
    if(l>r) return 0;
    int rt=hx[R];
    int p=l;
    while(zx[p]!=rt) p++;
    int cnt=p-l;
    lc[rt]=build(l,p-1,L,L+cnt-1);
    rc[rt]=build(p+1,r,L+cnt,R-1);
    return rt;
}
void dfs(int u,int sum)
{
    sum+=u;
    if(!lc[u]&&!rc[u])
    if(sum<ansum || (sum==ansum&&u<ans)) ansum=sum,ans=u;
    if(lc[u]) dfs(lc[u],sum);
    if(rc[u]) dfs(rc[u],sum);
}
int main()
{
    while(read(zx))
    {
        read(hx);
        build(0,n-1,0,n-1);
        ansum=0x7fffffff;
        dfs(hx[n-1],0);
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yearning/p/11341061.html