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 (根据中序遍历和后序遍历求先序遍历)

import java.util.Scanner; public class Main { static Scanner scan = new Scanner(System.in); stati...

UVa 548 Tree 根据后序遍历和中序遍历建树后DFS

#include #include #include #include #include #include #define PAUSE system("pause") using name...

Tree UVA - 548 

题目地址:UVA-548 一道炒鸡简单的题目硬生生WA了我十多次,最后发现是 --n和 n--搞反了。。。 练习的时候没什么。。 比赛的时候千万不要出现这种情况了。。 题目挺简单的,题目给出中...

Tree UVA548

这道题的做法很简单,就是根据二叉树的前序和后序序列建树,然后遍历这棵树。 但是我经过无数次的wa,rte之后才AC的。首先建树就出现问题,之后遍历时用DFS方法也不正确。DFS还是不怎么会用。 #i...

548 - Tree (UVa OJ)

Tree  You are to determine the value of the leaf node in a given binary tree that is the terminal...
  • SIOFive
  • SIOFive
  • 2013年08月04日 14:01
  • 923

UVA_548Tree

这是一个很经典的建树,然而当时不会!!!! 给你一个中序和后序 先建一个二叉树,然后找最优解(最优解就是一个叶子节点到根节点权值最小, 同时本身权值最小) //生成一棵树 int build...
  • xfzero
  • xfzero
  • 2015年09月08日 23:42
  • 131

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...

Uva548 Tree 二叉树遍历

/* 题目描述:见紫书155页 方法:这道题的一个收获就是若给出一棵树的中序遍历和后序遍历的结果,可以还原该树。 具体还原方法是后序遍历的最后一个节点是该...
  • jijijix
  • jijijix
  • 2016年08月12日 22:25
  • 83

UVA 548 Tree 中序+后序构造二叉树dfs

TreeYou are to determine the value of the leaf node in a given binary tree that is the terminal node...
  • dl2hq
  • dl2hq
  • 2017年03月18日 22:58
  • 83

UVa 548 Tree (中序遍历&后序遍历&DFS)

548 - Tree Time limit: 3.000 seconds  http://uva.onlinejudge.org/index.php?option=com_onlinejudge&...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVA 548 Tree
举报原因:
原因补充:

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