查找时用的时两节点到根的路径 让后从根开始往下遍历 直到两者的公共节点不同 或者有一方遍历完全
#define _CRT_SECURE_NO_WARNINGS
//给定一个 n个结点(编号 1∼n)构成的二叉树,其根结点为 1号点。进行 m次询问,每次询问两个结点之间的最短路径长度。树中所有边长均为 1
//输入格式
//第一行包含一个整数 T,表示共有 T组测试数据。
//每组数据第一行包含两个整数 n, m
//接下来 n行,每行包含两个整数,其中第 i行的整数表示结点 i的子结点编号。如果没有子结点则输出 −1
//接下来 m行,每行包含两个整数,表示要询问的两个结点的编号
//输出格式
//每组测试数据输出 m
//行,代表查询的两个结点之间的最短路径长度。
#include<stdio.h>
#include<vector>
using namespace std;
struct treenode {
int num;
treenode* left;
treenode* right;
treenode* parent;
};
int main() {
int T;
scanf("%d", &T);
for (int i = 0; i < T; i++) {
int n, m;
scanf("%d%d", &n, &m);
//开始建树 先把节点放入动态数组中再赋值
vector<treenode*> alltree(n + 1);
for (int i = 1; i <= n; i++) {
alltree[i] = new treenode;
alltree[i]->num = i;
}
//给树的节点左右孩子及父亲节点赋值
alltree[1]->parent = NULL;
int left, right;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &left, &right);
if (left != -1) {
alltree[i]->left = alltree[left];
alltree[left]->parent = alltree[i];
}
else {
alltree[i]->left = NULL;
}
if (right != -1) {
alltree[i]->right = alltree[right];
alltree[right]->parent = alltree[i];
}
else {
alltree[i]->right = NULL;
}
}
//开始测试用例 测距离节点
for (int j = 0; j < m; j++) {
int left, right;
scanf("%d%d", &left, &right);
vector<int> leftnum;
vector<int> rightnum;
treenode* p = alltree[left];
while (p != NULL) {
leftnum.push_back(p->num);
p = p->parent;
}
p = alltree[right];
while (p != NULL) {
rightnum.push_back(p->num);
p = p->parent;
}
//构建好两节点到根的路径
//根据路径判断两者的距离 这个路径判断时都是从根节点往下 直到两个有不同的节点则代表两者已经分开 上一个是最近的公共节点
int l, r;
l = leftnum.size()-1;
r = rightnum.size()-1;
while (1) {
if (l < 0 || r < 0 || leftnum[l] != rightnum[r]) {
break;
}
l--;
r--;
}
printf("%d\n", l + r + 2);
}
}
return 0;
}