#include <iostream>
#include <cstring>
using namespace std;
const int N = 200010, M = 2 * N, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], idx, n, m, k;
int f[N], g[N], cnt; //f[u]:u的子孙结点中,最近的特殊点距离u点的距离
//g[u]:u的子孙结点中,最远的没被特殊点覆盖的点距离u点的最远的距离
bool st[N];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs(int u, int father, int mid) {
f[u] = INF, g[u] = 0;
for (int i = h[u]; i != -1; i = ne[i]) {
int j = e[i];
if (j == father) continue;
dfs(j, u, mid);
f[u] = min(f[j] + 1, f[u]);
g[u] = max(g[j] + 1, g[u]);
}
if (f[u] + g[u] <= mid) g[u] = -INF;
else if (g[u] == mid) g[u] = -INF, f[u] = 0, cnt ++;
}
int check(int mid) {
cnt = 0;
dfs(1, -1, mid);
if (g[1] >= 0) cnt ++; //g[1] = 0说明1虽然被覆盖但是它的子节点还有没被覆盖的,且没被覆盖的点距离u的最远距离<mid
return cnt;
}
int main() {
memset(h, -1, sizeof h);
cin >> n >> k;
for (int i = 1; i < n; i ++) {
int a, b;
cin >> a >> b;
add(a, b), add(b, a);
}
int l = 1, r = n;
int ans = 1e9;
while (l < r) {
int mid = l + r >> 1;
if (check(mid) <= k) r = mid;
else l = mid + 1;
}
cout << l;
return 0;
}
Spread of Information
最新推荐文章于 2024-07-24 20:44:05 发布