|
|
#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 && !st[a[i].second]) {
|
|
|
//标识已使用
|
|
|
st[a[i].second] = 1;
|
|
|
//左结点为空,放入左结点
|
|
|
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);
|
|
|
} else if (a[i].second == u && !st[a[i].first]) {
|
|
|
st[a[i].first] = 1;
|
|
|
if (t[u].left == 0) t[u].left = a[i].first;
|
|
|
else t[u].right = a[i].first;
|
|
|
t[a[i].first].depth = t[u].depth + 1;
|
|
|
t[a[i].first].father = u;
|
|
|
dfs(a[i].first);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//最近公共祖先默认是根结点,就是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,与由根向叶结点方向(下行方向)时的边数之和。
|
|
|
//这里有一个最近公共祖先的问题,才能拿到正确答案
|
|
|
memset(st, 0, sizeof st);
|
|
|
int r = lca(u, v);
|
|
|
//按题意输出
|
|
|
cout << (t[u].depth - t[r].depth) * 2 + (t[v].depth - t[r].depth) << endl;
|
|
|
return 0;
|
|
|
} |