UVA 548 Tree(中序+后序还原二叉树)

来源:互联网 发布:nemo软件好用吗 编辑:程序博客网 时间:2024/05/21 05:06

【题目链接】UVA 548

【题意】已知二叉树的中序和后序遍历结果,求到根的路径上结点值之和最小的叶子结点的值。

【样例】

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

【分析】重点是根据中序和后序还原二叉树。这里要利用递归的思想。手动模拟大家都会,写出来还是有点难的…我给每个节点增加了value,sum,pre,leave的值(leave用来标记叶子结点),一遍建树之后找一下最小值就行了。

【总结】应该再实现一下先序+后序还原树。这题wa了无数发,最后把read_into()函数的return true改为return len>0就A了…刘汝佳是这样写的,网上大多数博客都是这样写的,但是想不明白为什么啊?测试了一下除非输入两个空行才会有差别,可是测试数据里不会有空呀?百思不得其解。

【代码】

#include<cstdio>#include<iostream>#include<algorithm>#include<sstream>#include<map>using namespace std;#define maxn 11000#define INF 1e18struct node{    int value,pre;    long long sum;    bool leave;};node tree[maxn];int in[maxn],post[maxn];int cnt,len;int build(int L1,int R1,int L2,int R2,int prev){    if(L1>R1) return 0;//空树    int root=post[R2];    cnt++;    int now=cnt;    if(L1==R1)        tree[cnt].leave=true;//标记叶子结点    tree[cnt].pre=prev;    tree[cnt].value=root;    tree[cnt].sum=tree[prev].sum+root;    int p=L1;    while(in[p]!=root)        p++;    int num=p-L1;    build(L1,p-1,L2,L2+num-1,now);    build(p+1,R1,L2+num,R2-1,now);    return 0;}bool read_into(int*a){    string line;    if(!getline(cin,line))        return false;    stringstream ss(line);    int x;    len=0;    while(ss>>x)        a[len++]=x;    return len>0;    //return true->wrong answer???}void init(){    tree[0].sum=0;    for(int i=0;i<=len;i++){        tree[i].leave=false;    }    return ;}int main(){    //freopen("test.txt","r",stdin);    while(read_into(in)){        read_into(post);        cnt=0;        init();        build(0,len-1,0,len-1,0);        long long ssum=INF,ans=INF;        for(int i=1;i<=cnt;i++){            if(tree[i].leave&&tree[i].sum<ssum){                ssum=tree[i].sum;                ans=tree[i].value;            }            else if(tree[i].leave&&tree[i].sum==ssum&&tree[i].value<ans){                ans=tree[i].value;            }        }        cout<<ans<<endl;    }    return 0;}

原创粉丝点击