思路是对深度维护 set,启发式合并。
#include <bits/stdc++.h>
#define int long long
#define set multiset
using namespace std;
const int maxn = 1e6 + 10;
int n, k, rt;
vector<int> g[maxn];
int deg[maxn];
int dep[maxn];
set<int> p[maxn];
void dfs(int u, int fa) {
dep[u] = dep[fa] + 1;
for (int v : g[u]) {
if (v == fa) continue;
dfs(v, u);
}
}
set<int> merge(set<int> u, set<int> v) {
if (u.size() < v.size()) swap(u, v);
while (v.size()) {
int x = *v.begin();
v.erase(x), u.insert(x);
}
return u;
}
void solve(int u, int fa) {
if (deg[u] == 1) return;
for (int v : g[u]) {
if (v == fa) continue;
solve(v, u);
}
set<int> res = set<int> (), nw = set<int> ();
for (int v : g[u]) res = merge(res, p[v]);
int x, y = *res.begin();
while (res.size() >= 2) {
x = *res.begin(), res.erase(res.find(x));
y = *res.begin();
if (x + y - dep[u] * 2 > k) nw.insert(x);
}
nw.insert(y);
p[u] = nw;
}
signed main() {
cin >> n >> k;
for (int i = 1, u, v; i < n; i++) {
cin >> u >> v;
g[u].push_back(v), g[v].push_back(u);
deg[u]++, deg[v]++;
}
for (int i = 1; i <= n; i++) if (deg[i] != 1) rt = i, i = n + 1;
dep[0] = -1;
dfs(rt, 0);
for (int i = 1; i <= n; i++) if (deg[i] == 1) p[i].insert(dep[i]);
solve(rt, 0);
cout << p[rt].size() << endl;
return 0;
}