根據後序中序輸出樹並且求解路徑權值和最小的葉子結點
阿新 • • 發佈:2018-12-29
題目描述:
給一顆點帶權(權值均為正整數並且小於10000)的二叉樹的中序和後序遍歷,找一個葉子是的它到根的路徑上的權和最小。如果有多解,輸出葉子權最小的那個。
輸入樣例兩行, 第一行為中序遍歷,第二行為後序遍歷,輸出葉子結點。
樣例輸入:
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
樣例輸出:
1
3
分析:先構建樹在利用bfs統計路徑權值和最小的即可,利用樹的中序和後序序列來建樹是一個遞迴的過程,資料結構都學過,就不贅述可,看程式碼,很清楚:
#include<iostream> #include<algorithm> #include<string> #include<sstream> using namespace std; const int maxn = 10000 +5; int in_order[maxn],post_order[maxn],lch[maxn],rch[maxn]; int n,best,best_sum; bool readList(int* a){ string line; if(!getline(cin,line)) return false; stringstream ss(line);//字串流 n = 0; int x; while(ss>>x) a[n++] = x;//將值寫入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);//左子樹 ,所以可知葉子結點的lch和rch均為0 rch[root] = build(p+1,R1,L2+cnt,R2-1);//右子樹 return root; } int dfs(int u,int sum){ sum += u; if(!lch[u]&&!rch[u]){//到了葉子結點開始判斷 if(sum < best_sum||(sum == best_sum&&u < best)){ best_sum = sum; best = u; } } if(lch[u]) dfs(lch[u],sum); if(rch[u]) dfs(rch[u],sum); } int main(){ while(readList(in_order)){ readList(post_order); best_sum = 1000000000; build(0,n-1,0,n-1,0); // for(int i = 0;i < n;i++){//檢視建樹之後的葉子結點 // int u = in_order[i]; // if(!lch[u]&&!rch[u]) // cout<<u<<endl; // } dfs(post_order[n-1],0); cout<< best << endl; } return 0; }