UVA_548Tree
这是一个很经典的建树,然而当时不会!!!!
给你一个中序和后序 先建一个二叉树,然后找最优解(最优解就是一个叶子节点到根节点权值最小, 同时本身权值最小)
//生成一棵树
int build(int L1, int R1, int L2, int R2) { //表示1为中序,2为后序 生成这个二叉树 其中R2为这棵树的根 if(L1 > R1) return 0; int root = post_order[R2]; int p = L1; while(in_order[p] != root) ++p; //在中序中找到根的位置 int cnt = p - L1; //cnt表示当前这棵树左子树的大小 lch[root] = build(L1, p-1, L2, L2 + cnt -1);//这里要知道在后序中,左子树(cnt),右子树,根 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 || (sum == best_sum && u < best)){ best = u;best_sum = sum; } } if(lch[u]) dfs(lch[u], sum); //接着递归 if(rch[u]) dfs(rch[u], sum);
}
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<queue> #include<cstdlib> #include<algorithm> #include<stack> #include<map> #include<queue> #include<vector> #include<sstream> using namespace std; const int maxn = 1e4+100; int in_order[maxn], post_order[maxn], lch[maxn], rch[maxn]; int n; 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) { if(L1 > R1) 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] && !rch[u]) { if(sum < best_sum || (sum == best_sum && u < best)){ best = u;best_sum = sum; } } if(lch[u]) dfs(lch[u], sum); if(rch[u]) dfs(rch[u], sum); } int main(){ #ifdef LOCAL freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif while(read_list(in_order)) { read_list(post_order); build(0, n-1, 0, n-1); best_sum = 1000000000; dfs(post_order[n-1],0); cout << best << "\n"; } return 0; }

浙公网安备 33010602011771号