树,Tree,UVA 548

题目链接:https://vjudge.net/problem/UVA-548

题解:这题是一道典型的二叉树数据结构题,核心在于,由二叉树的中序和后序遍历求先序遍历。解题的方法是,递归地先由后序遍历获得根结点,然后建立左子树和右子树,最后进行先序遍历,再按题目要求对先充遍历进行操作,输出结果。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<sstream>
#include<string>
#include<algorithm>
#include<climits>


using namespace std;

const int maxn = 1e5 + 10;


//BT structure
int b_data[maxn];
int b_left[maxn];
int b_right[maxn];
int root;
int cut = 0;

int in_order[maxn];
int pos_order[maxn];



int build_BT(int r1,int l1,int r2,int l2) {
	

	//end cond
	if (r1 > l1)return -1;

	//distrbute a root
	int root_index = cut++;
	int r = pos_order[l2];
	b_data[root_index] = r;


	int pos_i = r1;
	while (in_order[pos_i] != r)pos_i++;

	//build left
	b_left[root_index] = build_BT(r1, pos_i - 1, r2, r2 + pos_i - 1 - r1);


	//build right
	b_right[root_index] = build_BT(pos_i + 1, l1, r2 + pos_i - r1, l2 - 1);

	return root_index;

}

int value = 0;
int sumb = INT_MAX;

void pre_order(int r,int s) {
	if(b_left[r]==-1&&b_right[r]==-1){
		s += b_data[r];
		if (s < sumb) {
			sumb = s;
			value = b_data[r];
		}
		else if (s == sumb) {
			value = min(value, b_data[r]);
		}
	}

	if (b_left[r] != -1)
		pre_order(b_left[r], s + b_data[r]);
	if (b_right[r] != -1)
		pre_order(b_right[r], s + b_data[r]);

}

int main() {


	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);

	string s;
	while (getline(cin,s)) {
		stringstream ss(s);
		int n = 0;
		int cnt = 0;
		root = 0;
		cut = 0;
		while (ss >> n) {
			in_order[cnt++] = n;
		}
		getline(cin, s);
		ss = stringstream(s);
		n = 0;
		cnt = 0;
		
		while (ss >> n) {
			pos_order[cnt++] = n;
		}
		memset(b_data, 0, sizeof(b_data));
		memset(b_left, 0, sizeof(b_left));
		memset(b_right, 0, sizeof(b_right));
		sumb = INT_MAX;
		value = 0;

		//build
		root = build_BT(0, cnt - 1, 0, cnt - 1);

		//pre
		pre_order(root,0);

		cout << value << endl;

	}


}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值