You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
2.7 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
int n, x, y, u, v;
const int N = 110;
//树的结构体+存储数组
struct Node {
int id; // 当前结点ID
int father; // 爸爸
int left; // 左结点ID
int right; // 右结点ID
int depth; // 深度不用再次dfs去探测
} t[N];
//记录边的关系
typedef pair<int, int> PII;
PII a[N];
//是不是使用过
int st[N];
//用来计某一层的结点个数
int bucket[N];
//通过递归构建二叉树
void dfs(int u) {
//u是老大找出它的左儿子和右儿子
for (int i = 1; i < n; i++) {//遍历所有关系
if (a[i].first == u) {
//左结点为空,放入左结点
if (t[u].left == 0) t[u].left = a[i].second;
//否则放入右结点
else t[u].right = a[i].second;
//修改深度标识
t[a[i].second].depth = t[u].depth + 1;
t[a[i].second].father = u;
//递归创建子树
dfs(a[i].second);
}
}
}
//最近公共祖先默认是根结点就是1,英文简写lowestCommonAncestor
int lca(int x, int y) {
st[x] = 1; //把x的节点记录已走过
while (t[x].father) { //遍历至根节点
x = t[x].father; //更新遍历爸爸
st[x] = 1; //记录已走过
}
//遍历至x节点已走过的节点找到最近公共祖先
while (!st[y])y = t[y].father;
return y;
}
int main() {
//二叉树结点个数
cin >> n;
//接下来的n-1行
for (int i = 1; i < n; i++) {
//构建二叉树
cin >> x >> y;
//记录关系
a[i] = {x, y};
}
//通过递归建树,构建二叉树
t[1].depth = 1, t[1].id = 1, t[1].father = 0, st[1] = 1;//根结点1
dfs(1);
//表示求从结点u到结点v的距离
cin >> u >> v;
//二叉树的深度
int maxDepth = 0;
for (int i = 1; i <= n; i++) maxDepth = max(maxDepth, t[i].depth);
cout << maxDepth << endl;
//二叉树的宽度
int maxWidth = 0;
for (int i = 1; i <= n; i++) bucket[t[i].depth]++;
for (int i = 1; i <= n; i++) maxWidth = max(maxWidth, bucket[i]);
cout << maxWidth << endl;
//结点u到结点v间距离:结点间距离的定义由结点向根方向上行方向时的边数×2,与由根向叶结点方向(下行方向)时的边数之和。
//这里有一个最近公共祖先的问题,才能拿到正确答案
int r = lca(u, v);
//按题意输出
cout << (t[u].depth - t[r].depth) * 2 + (t[v].depth - t[r].depth) << endl;
return 0;
}