• 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;
    }
  • 相关阅读:
    LinkedList类源码浅析(一)
    ArrayList类源码浅析(三)
    我谁也没等,因为谁也不会来
    维持一段友谊
    最甜美的悲伤
    小美人访谈录笔记[1]
    1984我想对这个世界说些什么
    我喜欢我
    等不来的始终等不来,无须报以希望
    我抱有怀疑
  • 原文地址:https://www.cnblogs.com/yearning/p/11341061.html
Copyright © 2020-2023  润新知