二叉树的最短路径长度
已解决
题目描述
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';
}
}
}