洛谷P5536 【XR-3】核心城市
\(\Large\textbf{Description: } \large{有一棵n个节点的树,选择其中的k个相连的节点,求其余所有节点与选择节点之间的距离的最大值的最小值。(1 \leq n \leq 10^{5})}\\\)
\(\Large\textbf{Solution: } \large{首先一定有一个点在这棵数的直径上,因为如果不在,肯定无法比直径更优。\\然后我们可以从直径中点出发,每次往与中点距离最大的点扩展,扩展k次即可。\\}\\\)
\(\Large\textbf{Code: }\)
#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
using namespace std;
const int N = 1e5 + 5;
int n, k, cnt, Max, cur, m, head[N], dis[N], f[N], vis[N], d[N], ma[N];
struct Edge {
int to, next;
}e[N << 1];
inline int read() {
char ch = gc();
int ans = 0;
while (ch > '9' || ch < '0') ch = gc();
while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
return ans;
}
inline void add(int x, int y) {
e[++cnt].to = y;
e[cnt].next = head[x];
head[x] = cnt;
}
inline void dfs(int x, int fa) {
f[x] = fa;
dis[x] = dis[fa] + 1;
if (dis[x] > Max) Max = dis[x], cur = x;
for (int i = head[x]; i ; i = e[i].next) {
int u = e[i].to;
if (u == fa) continue;
dfs(u, x);
}
}
inline bool cmp(int x, int y) {
return x > y;
}
inline void dfs2(int x, int fa) {
dis[x] = ma[x] = dis[fa] + 1;
for (int i = head[x]; i ; i = e[i].next) {
int u = e[i].to;
if (u == fa) continue;
dfs2(u, x);
ma[x] = max(ma[x], ma[u]);
}
}
int main() {
n = read(), k = read();
int x, y;
rep(i, 2, n) x = read(), y = read(), add(x, y), add(y, x);
dfs(1, 0);
int l = cur; Max = 0, dfs(l, 0);
int r = cur, pre = 0;
for (int i = r; i ; i = f[i]) {
if (pre >= dis[r] / 2) { m = i; break; }
++pre;
}
dfs2(m, 0);
rep(i, 1, n) d[i] = max(d[i], ma[i] - dis[i]);
sort(d + 1, d + 1 + n, cmp);
printf("%d\n", d[k + 1] + 1);
return 0;
}