UVA 548 Tree

题目:  给出一棵二叉树的中序遍历和后序遍历,   求所在路径权值最小的叶子节点, 若权值相等取编号小的叶子。并且每个节点的权值都不同。

分析:   只要给出先序、中序、后续其中两个,,一棵二叉树就唯一确定了。   只需递归建树后就可以DFS求解了。 原问题就可以划分为两个简单的问题了。

所谓的先后序是指 根节点的先后顺序,儿子间的顺序总是左二子先于右儿子。

如:    中序:    d b e a f c g

            后序:   d e b f g c a

由后序可以确定根节点为 a,结合中序可知 d b e都是左儿子的节点,  f c g都是右儿子的节点。

由此可以得到一个递推建树的方法。  

求最小权值的过程是标准的DFS.


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=10010<<1;
int a[MAXN],b[MAXN],Lson[MAXN],Rson[MAXN],root;
int N,MinVal,Best;
int AD(int *s,int c){
	for(int p=0;p<N;p++){
		if(s[p]==c) return p;
	}
	return -1;
}
void Build(int n,int *a,int *b)
{
	int fa=b[n-1];
	if(n<=1){
		Lson[fa]=Rson[fa]=0; return;
	}
	int m=AD(a,fa);
	Lson[fa]= m==0?0:b[m-1] , Rson[fa]= m==n-1?0:b[n-2];
	if(Lson[fa]) Build(m,a,b);
	if(Rson[fa]) Build(n-m-1,a+m+1,b+m);
}
void DFS(int u,int val)
{
	if(!Rson[u] && !Lson[u]){
		if(val+u<MinVal){
			MinVal=val+u,Best=u;
		}else if(val+u==MinVal){
			Best=u<Best?u:Best;
		}
		return ;
	}
	if(Lson[u]) DFS(Lson[u],val+u);
	if(Rson[u]) DFS(Rson[u],val+u);
}
int main()
{
	while(scanf("%d",&a[0])!=EOF){
		N=1; 
		char c=getchar();
		while(c != '\n') scanf("%d",&a[N++]),c=getchar();
		for(int i=0;i<N;i++) scanf("%d",&b[i]); 
		root=b[N-1]; 
		Build(N,a,b);
		Best=MinVal=(int)1e9;
		DFS(root,0);
		printf("%d\n",Best);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值