顯然從葉子貪心是最優的。於是我們可以想到先取葉子,然後把葉子刪掉,然後繼續取葉子。
一共取 k/2 次葉子,如果k是奇數,最後再任意取一個點即可。
所以我們樹上拓撲即可。
AC程式碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e6+10;
int n,k,deg[N],dep[N],res;
vector<int> g[N]; queue<int> q;
signed main(){
cin>>n>>k;
for(int i=1,a,b;i<n;i++){
scanf("%d %d",&a,&b); deg[a]++,deg[b]++;
g[a].push_back(b),g[b].push_back(a);
}
if(k==0||k==1) return cout<<k,0;
for(int i=1;i<=n;i++) if(deg[i]==1) q.push(i),dep[i]=1;
while(q.size()){
int u=q.front(); q.pop(); res++;
for(int to:g[u]){
dep[to]=max(dep[to],dep[u]+1);
if(dep[to]<=k/2&&--deg[to]==1) q.push(to);
}
}
cout<<min(n,res+k%2);
return 0;
}