zoukankan      html  css  js  c++  java
  • UVa548

    题意:给一棵带权树(每个节点权值为正且不相等)的中序和后序遍历,找一个叶子使得它到根的路径的权值尽可能小,如果有多解取叶子权值小的。输入中每两行代表一棵树,第一行为中序遍历第二行后序遍历。

    分析:首先要搞清楚二叉树的先序(父左右)、中序(左父右)、后序(左右父)遍历的特点。后序遍历的最后一个字符就是根,然后坐在中序遍历中找到根,从而找出左右子树的节点列表,递归构造左右子树。而后再DFS遍历找最优解。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+5;
    int lch[maxn],rch[maxn],in_order[maxn],post_order[maxn],n;
    int build(int L1,int R1,int L2,int R2){
        if(L1>R1)    return  0;//空树返回0; 
        int root=post_order[R2];
        int cnt,p=L1;
        while(in_order[p]!=root)    p++;
        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,best_sum;
    void dfs(int u,int sum){
        sum+=u;
        if(!lch[u]&&!rch[u]){//叶子 
            if(sum<best_sum||(best_sum==sum&&best>u)){
                best_sum=sum;
                best=u;
            }
        }
        if(lch[u])    dfs(lch[u],sum);
        if(rch[u])    dfs(rch[u],sum);
    }
    
    bool input(int *a){
        string line;
        if(!getline(cin,line))    return false;
        stringstream ss(line);
        int x;
        n=0;
        while(ss>>x)    a[n++]=x;
        return n>0;
    }
    
    int main(){
        while(input(in_order)){
            input(post_order);
            build(0,n-1,0,n-1);
            best_sum=1e9;
            dfs(post_order[n-1],0);
            cout<<best<<endl;
        }
        return 0;
    }
  • 相关阅读:
    android OnActivityResult()的调用时机问题
    把汉化的eclipse还原为英语版的小绝招
    sunPKCS11加载动态库(转)
    android 源码分析
    android notification应用
    期待快点过去
    Linux 的Root 帐号
    C#之CMD
    更新Citrix Merchandising Server 2.2的默认Updater
    CRL的验证
  • 原文地址:https://www.cnblogs.com/depth/p/5742136.html
Copyright © 2011-2022 走看看