UVA 548 Tree

原创 2016年08月30日 09:20:21

题目链接 http://acm.hust.edu.cn/vjudge/problem/19105


题意:给定前序和后序遍历,找出从根到叶sum最小的路径,然后输出叶子上的值,如果有多条路径满足,输出叶子权值最小的。
分析:后序遍历的最后一个数就是根的值,因此只需在中序遍历中找到它,就知道左右子树的中序和后序遍历了。然后在不断递归,构造二叉树。 最后dfs找路径权值和最小的 


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <string>
#include <sstream>
#include <map>
#include <set>
#define pi acos(-1.0)
#define LL long long
#define ULL unsigned long long
#define inf 0x3f3f3f3f
#define INF 1e18
//#define lson l,mid,rt<<1
//#define rson mid+1,r,rt<<1|1
#define Deb(a) printf("---%d---\n", a);
#define mem0(a) memset(a, 0, sizeof(a))
#define memi(a) memset(a, inf, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
using namespace std;
typedef pair<int, int> P;
const double eps = 1e-10;
const int maxn = 1e6 + 5;
const int mod = 1e8;

int in_order[maxn], post_order[maxn];
int ans, mni, node, n;
struct Node{
	int lson, rson, val;
}tree[maxn];

bool read_list(int* a)
{
	string line;
	getline(cin, line);
	stringstream ss;
	ss << line;
	int x;
	n = 0;
	while (ss >> x) a[++n] = x;
	return n > 0;
}
int NewNode(int v){
	tree[++node].val = v;
	return node;
}
// 把in_oreder[L1..R1] 和 post_order[L2..R2]建成一棵二叉树,返回树根 
int MakeTree(int L1, int R1, int L2, int R2)
{
	if (L1 > R1) return 0; // 空树 
	int root = NewNode(post_order[R2]);
	int p = L1, cnt = 0;
	while (in_order[p] != post_order[R2]) 
		p++, cnt++;			// cnt为左子树的结点个数 
	int rootl = MakeTree(L1, L1+cnt-1, L2, L2+cnt-1);
	int rootr = MakeTree(p+1, R1, L2+cnt, R2-1);
	tree[root].lson = rootl;
	tree[root].rson = rootr;
	return root;
}
void dfs(int root, int sum)
{
	sum += tree[root].val;
	if (!tree[root].lson && !tree[root].rson){	// 叶子结点 
		if (mni > sum || (mni == sum && ans > tree[root].val))
			mni = sum, ans = tree[root].val;
		return;
	}
	if (tree[root].lson)
		dfs(tree[root].lson, sum);
	if (tree[root].rson)
		dfs(tree[root].rson, sum);
}
int main(void)
{
//	freopen("C:\\Users\\wave\\Desktop\\NULL.exe\\NULL\\in.txt","r", stdin);
	while (read_list(in_order)){
		read_list(post_order);
		node = 0; 
		int root = MakeTree(1, n, 1, n);
		mni = ans = inf;
		dfs(root, 0);
		printf("%d\n", ans);
	}

	return 0;
}


还有一种简单一点的做法,因为题目说各个点的权值不相同,所以可以直接把权值当做结点编号

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <string>
#include <map>
#include <set>
#include <sstream>
#define pi acos(-1.0)
#define LL long long
#define ULL unsigned long long
#define inf 0x3f3f3f3f
#define INF 1e18
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define debug(a) printf("---%d---\n", a)
#define mem0(a) memset(a, 0, sizeof(a))
#define memi(a) memset(a, inf, sizeof(a))
#define mem1(a) memset(a, -1, sizeof(a))
using namespace std;
typedef pair<int, int> P;
const double eps = 1e-10;
const int maxn = 1e6 + 5;
const int mod = 1e8;

// 因为各个结点的权值各不相同且都是正整数, 直接用权值作为结点编号 
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;
	ss << line; 
	n = 0;
	int x;
	while (ss >> x) a[n++] = x;
	return n > 0;
} 
// 把in_oreder[L1..R1] 和 post_order[L2..R2]建成一棵二叉树,返回树根 
int build(int L1, int R1, int L2, int R2){
	if (L1 > R1) return 0; // 空树 
	int root = post_order[R2];
	int p = L1, cnt = 0;
	while (in_order[p] != root) p++, cnt++; // cnt为左子树的结点个数 
	lch[root] = build(L1, L1+cnt-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(void)
{
//	freopen("C:\\Users\\wave\\Desktop\\NULL.exe\\NULL\\in.txt","r", stdin);
	while (read_list(in_order)){
		read_list(post_order);
		int root = build(0, n-1, 0, n-1);
		best_sum = inf;
		dfs(root, 0);
		cout << best << endl;
	}

	return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

uva 548 tree(中序后序还原树)

Tree  You are to determine the value of the leaf node in a given binary tree that is the term...
  • u011328934
  • u011328934
  • 2013年07月16日 12:52
  • 1468

uva 548 -Tree

You are to determine the value of the leaf node in a given binary tree that is the terminal node of ...
  • NiaNiaJR
  • NiaNiaJR
  • 2013年07月28日 15:14
  • 554

UVA - 548:Tree

You are to determine the value of the leaf node in a given binary tree that is the terminal node of ...
  • wingrez
  • wingrez
  • 2017年08月23日 18:27
  • 37

uva 548 tree 树

uva 548 tree
  • tengfei461807914
  • tengfei461807914
  • 2015年08月12日 01:04
  • 276

UVA - 548 Tree

You are to determine the value of the leaf node in a given binary tree that is the terminal node of ...
  • zz_FreeSky
  • zz_FreeSky
  • 2014年08月17日 14:24
  • 213

Uva - 548 - Tree

这道题目的输入需要注意,一般的都是先说测试数据包含多少个数据,比如中序遍历有多少个结点,再输入,而这里直接输入,回车判断是否结束,所以输入的时候可以先读一行,再用流存入数组。题目说了结点的权值各不相同...
  • zyq522376829
  • zyq522376829
  • 2015年06月15日 23:05
  • 568

uva 548 - Tree

给出一个树的中序遍历和一个树的后序遍历各个结点的值。 找出哪条路径到叶子结点的值(为各个结点之和)最小,如果有两条路径的相等,则取结束的结点较小的路径。 输出最后一个结点的值。 用中序遍历和后序遍历递...
  • u013791747
  • u013791747
  • 2014年03月01日 14:51
  • 519

UVa:548 Tree

这个题跪了好多次居然都是因为读错题了。 它要求在某条路径最小的情况下的叶结点的值。如果存在多条最小路径,则取最小的叶结点。 后序的最后一个结点是根节点。在中序序列中找到该结点的位置,右边是右子树,...
  • kkkwjx
  • kkkwjx
  • 2013年12月18日 17:18
  • 507

UVa 548 - Tree(二叉树)

二叉树的构建。
  • xuziye0327
  • xuziye0327
  • 2015年03月19日 13:11
  • 209

uva 548 tree

uva 548 tree You are to determine the value of the leaf node in a given binary tree that is the t...
  • llx523113241
  • llx523113241
  • 2014年12月27日 17:54
  • 380
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVA 548 Tree
举报原因:
原因补充:

(最多只允许输入30个字)