点分治板子而已
每次算一下到目前树根有多少条边就是了,取min
/*
有一个条件,就是要求边的数量最小,那么可以考虑,因为我们在模板中判断是否为k时时用的bool,我们可以开一个int.
它存下的值就是最短边数.
*/
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+50;
const int M=2e6+50;
int rt;
int sum;
int res;
int n,k;
int tot;
int cnt;
int s[N];
int x,y,z;
bool vis[N];
int head[N];
int judge[M];
int tmp[N],dis[N];
int siz[N],maxx[N];
struct Edge {
int u,v,w;
} edge[N*3];
void add(int x,int y,int z) {
edge[++tot].u=head[x];
edge[tot].v=y;
edge[tot].w=z;
head[x]=tot;
return ;
}
void getrt(int x,int f) {
siz[x]=1;
maxx[x]=0;
for(int i=head[x]; i; i=edge[i].u) {
int to=edge[i].v;
if(to==f||vis[to]) continue;
getrt(to,x);
siz[x]+=siz[to];
maxx[x]=max(maxx[x],siz[to]);
}
maxx[x]=max(maxx[x],sum-siz[x]);
if(maxx[x]<maxx[rt]) rt=x;
return ;
}
void getdis(int x,int f,int bian) {
if(dis[x]>1e6) return ;
tmp[++cnt]=dis[x];
s[cnt]=bian;
for(int i=head[x]; i; i=edge[i].u) {
int to=edge[i].v;
if(to==f||vis[to]) continue;
dis[to]=dis[x]+edge[i].w;
getdis(to,x,bian+1);
}
return ;
}
void solve(int x) {
queue<int> que;
for(int i=head[x]; i; i=edge[i].u) {
int to=edge[i].v;
if(vis[to]) continue;
cnt=0;
dis[to]=edge[i].w;
getdis(to,x,1);
for(int j=1; j<=cnt; ++j)
if(k>=tmp[j])
res=min(res,s[j]+judge[k-tmp[j]]);
for(int j=1; j<=cnt; ++j) {
que.push(tmp[j]);
judge[tmp[j]]=min(judge[tmp[j]],s[j]);
}
}
while(!que.empty()) {
judge[que.front()]=0x3f3f3f3f;
que.pop();
}
return ;
}
void divide(int x) {
vis[x]=true;
judge[0]=0;
solve(x);
for(int i=head[x]; i; i=edge[i].u) {
int to=edge[i].v;
if(vis[to]) continue;
maxx[rt=0]=sum=siz[to];
getrt(to,0);
getrt(rt,0);
divide(rt);
}
return ;
}
int main() {
// freopen("race.in","r",stdin);
// freopen("race.out","w",stdout);
res=0x3f3f3f3f;
memset(judge,0x3f,sizeof judge);
scanf("%d%d",&n,&k);
for(int i=1; i<n; ++i) {
scanf("%d%d%d",&x,&y,&z);
x++;
y++;
add(x,y,z);
add(y,x,z);
}
maxx[0]=sum=n;
getrt(1,0);
getrt(rt,0);
divide(rt);
if(res==0x3f3f3f3f) printf("-1\n");
else printf("%d\n",res);
return 0;
}