题目大意
节点2和节点3最近的共同祖先是节点10,节点6和节点13最近的共同祖先是节点8,节点4和节点12最近的共同祖先是节点4。在最后一个例子中,如果y是z的祖先,那么y和z最近的共同祖先就是y,编写一个程序,找到树中两个不同节点最近的共同祖先。
思路分析
看着树很复杂,但是我们只需要维护叶子与根的关系即可,求得是从a和b的最近公共祖先,我们先对a操作,不断进行a=root[a]
直到根节点,记录所有a
的根,然后对b
进行操作,找到第一个是b的根而且a也有记录的根,就是需要的结果
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
#include<algorithm>
#include<cstdio>
#include<queue>
using namespace std;
#define MAX 10005
#define ll int
#define p pair<int,int>
#define inf 1111111111
ll T, N, a, b;
ll root[MAX], r[MAX];
int main() {
cin >> T;
while (T--) {
cin >> N;
memset(root, 0, sizeof(root));
memset(r, 0, sizeof(r));
for (int i = 0; i < N - 1; i++) {
cin >> a >> b;
root[b] = a;
}
cin >> a >> b;
while (a) {//到了树的根部 root[a]==0
r[a] = 1;// r中存储a的所有根
a = root[a];
}
while (b) {
if (r[b]) {//根b也是a的根,也就是最近的祖辈节点
cout << b << endl;
break;
}
b = root[b];
}
}
}