原理
问题目标:根据输入的父子关系,找到小明(编号1)和小宇(编号2)的 共同祖先,并比较两人在该祖先下的辈分关系(长辈、晚辈或兄弟)。
核心思路:
- 假设存在共同根节点:通过遍历所有输入的父节点,记录最大的父节点值
maxnum
,假设其为整个族谱的 根节点。 - 计算到根节点的步数:从小明和小宇分别向上遍历父节点,直到到达
maxnum
或父节点不存在,统计步数counta
和countb
。 - 比较步数:若
counta > countb
,说明小明辈分更高;反之小宇辈分更高;步数相同则为兄弟。
步骤
- 输入处理:读取父子关系,用哈希表
map
存储(键为子节点,值为父节点),并记录最大的父节点值maxnum
。 - 计算小明到根节点的步数:从节点1出发,依次向上遍历父节点,直到父节点为
maxnum
或不存在,统计步数counta
。 - 计算小宇到根节点的步数:同理从节点2出发,统计步数
countb
。 - 比较步数:根据
counta
和countb
的大小输出结果。
图示法表示步骤(输入父子关系:[[1,3],[3,5],[2,4],[4,5]]
)
1. 输入处理:
map = {1→3, 3→5, 2→4, 4→5}
maxnum = 5(所有父节点中的最大值)
2. 小明路径:1 → 3 → 5(共2步)
小宇路径:2 → 4 → 5(共2步)
3. 比较步数:counta=2,countb=2 → 输出 "You are my brother"
代码关键行注释
int main() {
int n;
while (cin >> n) {
int a, b;
int counta = 0, countb = 0;
int maxnum = 0;
unordered_map<int, int> map; // 存储父子关系(子→父)
for (int i = 0; i < n; i++) {
cin >> a >> b;
map[a] = b;
maxnum = max(maxnum, b); // 记录最大的父节点值(假设为根节点)
}
// 计算小明到根节点的步数
a = 1;
while (map[a] && map[a] != maxnum) { // 遍历父节点,直到到达maxnum或父节点不存在
a = map[a];
counta++;
}
// 计算小宇到根节点的步数
b = 2;
while (map[b] && map[b] != maxnum) {
b = map[b];
countb++;
}
// 比较步数输出结果
if (counta > countb)
cout << "You are my elder" << endl;
else if (counta < countb)
cout << "You are my younger" << endl;
else
cout << "You are my brother" << endl;
}
}
完整代码
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main() {
int n;
while (cin >> n) {
int a, b;
int counta = 0, countb = 0;
int maxnum = 0;
unordered_map<int, int> map;
for (int i = 0; i < n; i++) {
cin >> a >> b;
map[a] = b;
maxnum = max(maxnum, b);
}
a = 1;
while (map[a] && map[a] != maxnum) {
a = map[a];
counta++;
}
b = 2;
while (map[b] && map[b] != maxnum) {
b = map[b];
countb++;
}
if (counta > countb)
cout << "You are my elder" << endl;
else if (counta < countb)
cout << "You are my younger" << endl;
else
cout << "You are my brother" << endl;
}
}
时间复杂度
- 时间复杂度:
- 输入处理:O(n),遍历
n
对父子关系。 - 计算步数:最坏 O(h),其中
h
是树的高度。 - 总体时间复杂度:O(n+h),通常为线性复杂度。
- 输入处理:O(n),遍历
- 空间复杂度:O(n),存储哈希表
map
。
总结
- 算法正确性:
- 假设输入数据构成单根树:即所有节点最终指向同一个根节点
maxnum
。若输入不满足此条件(如存在多个根节点),代码可能错误。 - 示例验证(如上述父子关系)结果正确。
- 假设输入数据构成单根树:即所有节点最终指向同一个根节点
- 代码特点:
- 简化了族谱链的存储,直接通过遍历父节点计算步数。
- 依赖
maxnum
作为根节点的假设,适用于题目隐含单根树的场景。
- 潜在问题:
- 若存在多个根节点或共同祖先非
maxnum
,结果可能错误。例如,父子关系为[[1,3],[3,4],[2,5]]
,maxnum=5
,但小明和小宇无共同祖先,代码仍会输出错误结果。
- 若存在多个根节点或共同祖先非