直接上代码。。。
(另外也可以在递归的时候统计最优解,不过程序稍微复杂一点)
#include <iostream> #include <string> #include <sstream> using namespace std; const int maxn=10000+10; int in_order[maxn],post_order[maxn],lch[maxn],rch[maxn]; int n; bool read_list(int *a){//输入一行用空格分隔的正整数,然而却没有明显的个数,for循环行不通 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){//或L2>R2 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,best_sum;//当前最优解 void dfs(int u,int sum){ sum+=u; if(lch[u]) dfs(lch[u],sum); if(rch[u]) dfs(rch[u],sum); if(!lch[u]&&!rch[u]) { if(sum<best_sum||(sum==best_sum&&u<best)){ best_sum=sum; best=u; } } return; } int main(){ while(read_list(in_order)){ read_list(post_order); build(0,n-1,0,n-1); best_sum=100000000;//10000*10000 dfs(post_order[n-1],0); cout<<best<<" "; } return 0; }