三叉树--北航

题目描述:

题目链接

Time Limit: 1000 ms
Memory Limit: 256 mb
一个关于三叉树的题目,小于100的值代表树叶,大于100的值为分支点,建树的过程是水平方向建树,

输入格式:

先输入n,代表有n组数据,接下来n行,输入4个数,第一个数代表根节点,接下来分别代表三个子节点,-1代表子节点不存在,输入的顺序按照层次遍历的次序。接下来,要求寻找叶子节点的最短路径,最短路径是指不经过重复的边。输入方式,首先输入一个值m,代表m行,接下来m行输入m个叶子节点和对应的优先级,要求按优先级输出从上次到达的位置到该节点的最短路径,每条路径的最后一个节点要求输出目标叶子节点,最后要求回到根节点。
在这里插入图片描述

思路:

第一条路径就是从叶子节点找到根节点
后面的路径:
首先要保存上一条路径
①如果在当前叶子节点找根节点的路径中出现了上一条路径中的节点,那么就可以直接把上一条路径中该节点以后的非叶子节点直接拷贝过来,加入到当前的路径中即可。(注意顺序)
②如果当前叶子节点找根节点的路径中没有出现上一条路径中的节点,即到达了根节点。那么后面的只需把上一条路径最后的非叶子节点到根节点的路径加入到当前路径中即可。(注意顺序)

代码:

#include<bits/stdc++.h>
using namespace std;
struct TreeNode{  //构建节点 
	int pre;
	int child[3];
	TreeNode(){
		pre=-1;
	}
};
bool exist(vector<int> ve,int x){ //判断节点x是否在pre数组中 
	if(find(ve.begin(),ve.end(),x)!=ve.end()) return true;
	return false;
}
int main(){
	int m,n,a,b,c,x,i,j;
	while(cin>>n){
		TreeNode node[10000];
		while(n--){ //建立三叉树 
			cin>>x>>a>>b>>c;
			node[x].child[0]=a,node[x].child[1]=b,node[x].child[2]=c;
			if(a!=-1) node[a].pre=x;
			if(b!=-1) node[b].pre=x;
			if(c!=-1) node[c].pre=x;
		}
		cin>>m;
		vector<int> ve(m);
		while(m--){ //设置优先级,根据优先级进行输出 
			cin>>a>>b;
			ve[b]=a;
		}
		vector<int> pre; //保存上一条路径 
		
		for(i=0;i<ve.size();i++){
			vector<int> temp; //保存这一条路径 
			bool flag=false;
			int tmp=ve[i]; //叶子节点 
			temp.push_back(tmp);
			while(node[tmp].pre!=-1){ //到了根节点 
				temp.push_back(node[tmp].pre);
				if(exist(pre,node[tmp].pre)){  //如果上一条路径中有该节点,直接从上一条路径该节点后面的非叶子节点拷贝过来(注意顺序) 
					flag=true;
					break;
				}
				tmp=node[tmp].pre;
			}
			if(flag){ //拷贝上一条路径该节点后面的非叶子节点
				bool f=false;
				for(j=pre.size()-1;j>=0;j--){
					if(f&&pre[j]>=100) temp.push_back(pre[j]);
					if(pre[j]==node[tmp].pre) f=true;
				}
			}else{ //到达根节点,从上一条路径结尾处找根节点(注意顺序) 
				if(i!=0){
					int root=tmp;
					int nn=pre[1];
					int x=temp.size();
					while(node[nn].pre!=-1){
					//	cout<<nn<<endl;
						temp.insert(temp.begin()+x,nn);
						nn=node[nn].pre;
					}
				}
				
			}
			for(j=temp.size()-1;j>=0;j--){ //输出路径 
				if(j!=0) cout<<temp[j]<<" ";
				else cout<<temp[j]<<endl;
			}
			pre=temp;
		}
		//处理最后节点到根节点的路径 
		int t=pre[1];
		vector<int> temp;
		while(t!=-1){
			temp.push_back(t);
			t=node[t].pre;
		}
		for(j=0;j<temp.size();j++){//输出 
			if(j==temp.size()-1) cout<<temp[j]<<endl;
			else cout<<temp[j]<<" ";
		}
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值