#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int n /*节点数*/, k /*要选出的节点数,定义一个节点的最短距离为到这 k 个节点的最短距离,选出 k 个节点,使得最大的最短距离最小*/;
int max_depth /*最大深度*/, max_depth_node /*最大深度的节点*/;
int f[MAXN]; // 记录每个节点的父节点(以直径的一端为根节点)
vector<int> a[MAXN];
int depth[MAXN] /*记录每个节点的深度*/, maxdepth[MAXN] /*记录每个节点到离他最远的节点的距离*/;
int max_dist[MAXN] /*记录每个节点到离他最远的节点的距离*/;
int ans /*答案*/;
/// @brief 排序比较函数
/// @param a 第一个数
/// @param b 第二个数
/// @return 如果 a > b,返回 true;否则返回 false
bool cmp(int a, int b)
{
return a > b; // 降序排序
}
/// @brief DFS求初始点到其子节点的最远距离和最远距离的节点,顺便求出以初始点为根节点的树的直径
/// @param u 初始点
/// @param fa 父节点
/// @param depth 当前节点的深度
void getMaxDist(int u, int fa, int depth)
{
if (depth > max_depth) // 如果当前节点的深度大于最大深度,更新最大深度和最大深度的节点
{
max_depth = depth; // 更新最大深度
max_depth_node = u; // 更新最大深度的节点
}
for (int v : a[u]) // 遍历当前节点的子节点
if (v != fa) // 跳过父节点
{
f[v] = u; // 记录子节点的父节点
getMaxDist(v, u, depth + 1); // 递归求子节点的最远距离
}
}
/// @brief DFS更新数组 depth 和 maxdepth
/// @param u 当前节点
/// @param fa 父节点
void update_depth_and_maxdepth(int u, int fa)
{
maxdepth[u] = depth[u]; // 初始时,每个节点的最远距离就是它自己的深度
for (int v : a[u]) // 遍历当前节点的子节点
if (v != fa) // 跳过父节点
{
update_depth_and_maxdepth(v, u); // 递归更新子节点的深度和最远距离
maxdepth[u] = max(maxdepth[u], maxdepth[v]); // 更新当前节点的最远距离
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> n >> k; // 读入节点数和要选出的节点数
for (int i = 1; i < n; ++i) // 读入边
{
int u, v; // 读入边的两个端点
cin >> u >> v; // 读入边的两个端点
a[u].push_back(v); // 建立 u -> v 的边
a[v].push_back(u); // 建立 v -> u 的边
}
getMaxDist(1, 0, 0); // 调用 DFS 算法求初始点到其子节点的最远距离和最远距离的节点,顺便求出以初始点为根节点的树的直径
getMaxDist(max_depth_node, 0, 0); // 调用 DFS 算法求最大深度的节点到其子节点的最远距离和最远距离的节点,顺便求出以最大深度的节点为根节点的树的直径
int mid_of_diameter = max_depth_node; // 假设最大深度的节点(一定是叶子节点)为直径的中点
for (int i = 1; i <= (max_depth + 1) / 2; ++i) // 求直径的中点
mid_of_diameter = f[mid_of_diameter];
update_depth_and_maxdepth(mid_of_diameter, 0); // 更新数组 depth 和 maxdepth
for (int i = 1; i <= n; ++i) // 遍历所有节点
max_dist[i] = maxdepth[i] - depth[i]; // 计算每个节点到离它最远的节点的距离
sort(max_dist + 1, max_dist + n + 1, cmp); // 排序
for (int i = k + 1; i <= n; ++i) // 选出 k 个节点
ans = max(ans, max_dist[i] + 1); // 记录答案
cout << ans << '\n'; // 输出答案
return 0;
}
悬 2 关