二叉树的最短路径长度(BFS+DFS)

二叉树的最短路径长度

已解决

查看题解查看答案

题目描述

Time Limit: 1000 ms

Memory Limit: 256 mb

对二叉树,计算任意两个结点的最短路径长度。

输入输出格式
输入描述:

第一行输入测试数据组数 T 第二行输入 n , m 。 n 代表输入的数据组数, m 代表要查询的数据组数。 接下来 n 行,每行输入两个数,代表1~ n 结点的孩子结点,如果没有孩子结点则输入-1,根节点为1。 接下来 m 行,每行输入两个数,代表要查询的两个结点。

输出描述:

每组测试数据输出 m 行,代表查询的两个结点之间的最短路径长度。

输入输出样例
输入样例#:

复制

复制代码
1
8 4
2 3
4 5
6 -1
-1 -1
-1 7
-1 -1
8 -1
-1 -1
1 6
4 6
4 5
8 1
输出样例#:

复制

复制代码
2
4
2
4
题目来源
复制代码
北京邮电大学机试题
复制代码
#include<bits/stdc++.h>
using namespace std;

//10000容易超时 
#define N 100005

int lch[N], rch[N];//i节点的左右孩子 
int parent[N];//i节点的最严厉的父亲
int depth[N];//i节点的深度 

void DFS(int u){
	if(lch[u] != -1){//节点不为空 
		depth[lch[u]] = depth[u] + 1;//等于它父亲的高度+1 
		DFS(lch[u]); 
	}
	
	if(rch[u] != -1){
		depth[rch[u]] = depth[u] + 1;
		DFS(rch[u]); 
	}
}

int getDist(int u, int v){
	int count = 0;
	
	while(depth[u] > depth[v]){//如果u更深就往上爬 
		u = parent[u];
		count ++;
	}
	
	while(depth[v] > depth[u]){//如果v更深就往上爬 
		v = parent[v];
		count ++;
	}
	
	while(u != v){//同时网上爬 
		u = parent[u];
		v = parent[v];
		count += 2;
	}
	
	return count;
	
}


int main(){
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	int t;
	cin>>t;
	while(t--){
		int n, m;
		cin>>n>>m;
		
		for(int i = 0; i <= n; i ++){//全部初始化 , 包括0, 否则会污染数据, 无法通过
			lch[i] = rch[i] = -1;
			parent[i] = 0;
			depth[i] = 0;
		}
		
		for(int i = 1; i <= n; i ++){//先输入节点 
			cin>>lch[i]>>rch[i];
		}
		
		for(int i = 1; i <= n; i ++){//认爹大法 
			if(lch[i] != -1){//左孩子不是空
				parent[lch[i]] = i;//认爹 
			} 
			if(rch[i] != -1){//右孩子不是空 
				parent[rch[i]] = i;//认爹 
			}
		}
		
		depth[1] = 0;//根节点高度为0
//		DFS(1);//深度遍历 
		queue<int>q;
		q.push(1);//根节点入队
		
		while(!q.empty()){//BFS遍历深度 
			int i = q.front();
			q.pop();
			
			if(lch[i] != -1){//有左孩子
				depth[lch[i]] = depth[i] + 1;
				
				q.push(lch[i]);//左孩子进去
			}
			
			if(rch[i] != -1){
				depth[rch[i]] = depth[i] + 1;
				
				q.push(rch[i]);
			}
			
		} 
		
		while(m --){
			int u, v;
			cin>>u>>v;
			cout<<getDist(u, v)<<'\n';
		}
		
		
		
	}
	
	

	
	
	
	
}
相关推荐
一条大祥脚几秒前
ABC461 枚举|扫描线|动态前缀和|数论|dfs枚举子集
算法·深度优先
计算机安禾3 分钟前
【数据库系统原理】第14篇:关系模式的语义约束:函数依赖的公理系统与闭包计算
人工智能·算法·机器学习
量化君也5 分钟前
快速入门量化交易都要学些什么?
大数据·人工智能·python·算法·金融
AbandonForce15 分钟前
滑动窗口:定长滑动窗口与不定长滑动窗口
数据结构·c++·算法
炸薯条!28 分钟前
二叉树的链式表示(2)
java·数据结构·算法
Tairitsu_H31 分钟前
[LC优选算法#2] 滑动窗口 | 长度最小的子数组 | 无重复字符的最长子串 | 最大连续1的个数
算法
小欣加油32 分钟前
leetcode3689最大子数组总值I
c++·算法·leetcode·职场和发展·贪心算法
下午写HelloWorld40 分钟前
【概念与应用】轻量级加密算法LEA、动态脱敏算法DDA、零知识证明ZKP和优化协同交互协议OCIP
算法·区块链·密码学·安全架构·零知识证明
飞舞哲1 小时前
三维点云最小二乘拟合MATLAB程序
开发语言·算法·matlab
Coder-magician1 小时前
《代码随想录》刷题打卡day12:二叉树part02
数据结构·c++·算法