思路:树的直径+优先队列
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct sss {
int w, x;
bool operator<(const sss& a)const {
return w < a.w;
}
};
bool st[200010];
int h[200010], e[300010], ne[300010], idx, deep[200010], maxi, maxj, d[200010], midroot;
void add(int a, int b) {
ne[idx] = h[a], e[idx] = b, h[a] = idx++;
return;
}
void bfs() {
queue<int>q;
q.push(1);
deep[1] = 1;
while (q.size()) {
int u = q.front();
q.pop();
maxi = u;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (deep[j] <= deep[u])continue;
deep[j] = deep[u] + 1;
q.push(j);
}
}
return;
}
void bfs2(int sta) {
queue<int>q;
q.push(sta);
d[sta] = 1;
while (q.size()) {
int u = q.front();
q.pop();
maxj = u;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (d[j] <= d[u])continue;
d[j] = d[u] + 1;
q.push(j);
}
}
return;
}
bool dfs(int u, int fa, int dist) {
if (u == maxj)return true;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == fa)continue;
if (dfs(j, u, dist + 1)) {
if (dist == d[maxj] >> 1) midroot = u;
return true;
}
}
return false;
}
int dfs2(int u, int fa) {
int w = 0;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == fa)continue;
w = max(w, dfs2(j, u));
}
return w + 1;
}
signed main() {
memset(d, 0x3f, sizeof d);
memset(deep, 0x3f, sizeof deep);
int n, k;
cin >> n >> k;
memset(h, -1, sizeof h);
for (int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
add(u, v);
add(v, u);
}
bfs();
bfs2(maxi);
dfs(maxi, 0, 0);
priority_queue<sss>q;
int maxx = 0;
st[midroot] = true;
for (int i = h[midroot]; i != -1; i = ne[i]) {
int j = e[i];
q.push({ dfs2(j, midroot), j });
st[j] = true;
}
for (int kk = 1; kk < k; kk++) {
sss now = q.top();
q.pop();
for (int i = h[now.x]; i != -1; i = ne[i]) {
int j = e[i];
if (st[j])continue;
st[j] = true;
q.push({ now.w - 1, j });
}
}
if (!q.size()) cout << 0;
else cout << q.top().w;
return 0;
}