题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=489
思路:根据输入的后序遍历(最后的那个数)找到树根,然后再在给出的中序遍历中找到树根,这样就能根据后序中序遍历的数据递归构造左右子树,最后dfs求出最优解
Code:
#include <iostream>
#include <sstream>
#include <string.h>
#include <cstdio>
#define INF 0x3f3f3f
using namespace std;
const int AX = 1e4+666;
int in_order[AX],post_order[AX],l[AX],r[AX];
int n;
int node,res;
bool read_List( 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 L1 , int R1 , int L2, int R2){ //把in_order[L1--R1]和post_order[L2--R2]建成一颗二叉树,返回树根。
if( L1 > R1 ) return 0;
int root = post_order[R2];
int p = L1;
while( in_order[p] != root ) p++;
int cnt = p - L1;
l[root] = build(L1,p-1,L2,L2+cnt-1);
r[root] = build(p+1,R1,L2+cnt,R2-1);
return root;
}
void DFS(int u , int sum){
sum += u;
if( !l[u] && !r[u] ){
if( sum < res || ( sum == res && node > u )){
node = u;
res = sum;
}
}
if( l[u] ) DFS( l[u] , sum );
if( r[u] ) DFS( r[u] , sum );
}
int main(){
while(read_List(in_order)){
read_List(post_order);
build(0,n-1,0,n-1);
res = INF;
DFS(post_order[n-1],0);
cout << node << endl;
}
return 0;
}