uva 548 Tree

本文介绍了一种利用中序和后序遍历来构建树,并找出从叶子节点到根节点最短路径的方法。通过递归构造树结构,再采用深度优先搜索策略求解最短路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:Tree


题意:输入一颗树的中序遍历和后序遍历,输出这可数从叶子结点到根节点的最短路径。


思路:

1、根据中序遍历和后序遍历建树。

因为后序遍历的最后一个数一定是根节点,所以对于每一颗子树,都可以在中序遍历中根据跟姐点再划分成两颗子树。因此可以递归建树。

2、求解最短路径。

我的做法是从根节点向下dfs找最优解。可能保存父节点从下至上更快一些吧。


注意:输入很讨厌。

书上的输入(好像有点慢):

bool read_list(int* a) {
	string line;
	if(!getline(cin, line)) return false;
	stringstream ss(line);
	n = 0;
	int x;
	while(ss >> x) a[n++] = x;
	return n > 0;
}

代码:

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
using namespace std;

struct Node {
	int value,left,right;
	Node() {}
	Node(int one,int two,int three) {
		value=one,left=two,right=three;
	}
};

struct F {
	int x,value;
	F() {}
	F(int one,int two) {
		x=one,value=two;
	}
	bool operator <(const F& other) const {
		if(value<other.value||(value==other.value&&x<other.x)) return true;
		return false;
	}
};

vector<int> t1,t2;
vector<Node> vec;

bool readin() {
	t1.clear(),t2.clear(),vec.clear();
	int x;
	char y;
	while(scanf("%d%c",&x,&y)==2) {
		t1.push_back(x);
		if(y=='\n'||y=='\r') break;
	}
	if(t1.empty()) return false;
	for(int i=0; i<t1.size(); i++) {
		scanf("%d",&x),t2.push_back(x);
	}
	getchar();
	return true;
}

int make_tree(vector<int> a,vector<int> b) {
	if(a.empty()||b.empty()) return -1;
	vector<int> cut1,cut2,cut3,cut4;
	int cut;
	for(int i=0; i<a.size(); i++) {
		if(a[i]==b[b.size()-1]) {
			cut=i;
			break;
		}
	}
	for(int i=0; i<cut; i++) {
		cut1.push_back(a[i]),cut3.push_back(b[i]);
	}
	for(int i=cut+1; i<b.size(); i++) {
		cut2.push_back(a[i]);
		if(i>0) cut4.push_back(b[i-1]);
	}
	int l=make_tree(cut1,cut3),r=make_tree(cut2,cut4);
	vec.push_back(Node(a[cut],l,r));
	return vec.size()-1;
}

F dfs(int x) {
	F l,r;
	if(vec[x].left==-1&&vec[x].right==-1) return F(vec[x].value,vec[x].value);
	else if(vec[x].left==-1) {
		r=dfs(vec[x].right);
		r.value+=vec[x].value;
		return r;
	} else if(vec[x].right==-1) {
		l=dfs(vec[x].left);
		l.value+=vec[x].value;
		return l;
	} else {
		l=dfs(vec[x].left),r=dfs(vec[x].right);
		l.value+=vec[x].value,r.value+=vec[x].value;
		return min(l,r);
	}
}

int main() {
	while(readin()) {
		make_tree(t1,t2);
		printf("%d\n",dfs(vec.size()-1).x);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值