两遍 bfs 求树的直径,第三遍求以直径中点为根各个点的深度。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n,k;
struct node{
int to,next;
}tr[2 * N];
int h[N], idx = 0;
void add(int from,int to){
tr[++idx].to = to;
tr[idx].next = h[from];
h[from] = idx;
}
int d[N],dd,fa[N],id;
bool vis[N];
queue<int> q;
int maxdeep[N],deep[N];
void bfs(int x){
while(!q.empty()) q.pop();
memset(d,0,sizeof(d));
memset(fa,0,sizeof(fa));
memset(vis,0,sizeof(vis));
q.push(x);vis[x] = true;
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = h[u] ; i ; i = tr[i].next){
int y = tr[i].to;
if(!vis[y]){
d[y] = d[u] + 1;
vis[y] = true;
fa[y] = u;
q.push(y);
}
}
}
for(int i = 1 ; i <= n ; i ++) if(dd < d[i]) id = i,dd = d[i];
}
void dfs(int x,int last){
maxdeep[x] = d[x];
for(int i = h[x] ; i ; i = tr[i].next){
int y = tr[i].to;
if(y != last){
dfs(y,x);
maxdeep[x] = max(maxdeep[x],maxdeep[y]);
}
}
}
bool cmp(int aa,int bb) {return aa > bb;}
int main(){
cin >> n >> k;
for(int i = 1 ; i < n ; i ++){
int u,v;
cin >> u >> v;
add(u,v);add(v,u);
}
bfs(1);
bfs(id);
for(int i = 1 ; i <= (dd + 1) / 2 ; i ++) id = fa[id];
bfs(id);
// memset(d,0,sizeof(d));
dfs(id,-1);
for(int i = 1 ; i <= n ; i ++) deep[i] = maxdeep[i] - d[i];
sort(deep + 1,deep + 1 + n,cmp);
cout << deep[k + 1] + 1;
return 0;
}