做法是t[i]表示到根距离为i的最小边数 A了两个点,剩下的都是TLE 代码如下
#include<bits/stdc++.h>
using namespace std;
#define y to[i]
const int maxn=2e6+10;
int head[maxn],to[maxn<<1],val[maxn<<1],nxt[maxn<<1],tot=0;
int n,k;
void add(int x,int c,int z)
{
to[++tot]=c;
nxt[tot]=head[x];
head[x]=tot;
val[tot]=z;
}
int ans=0x7f7f7f7f;
int vis[maxn];
int t[1000010];
int sz[maxn],tsz,maxp[maxn],rt;
void getroot(int x,int f)
{
sz[x]=1;
maxp[x]=0;
for(int i=head[x];i;i=nxt[i])
{
if(vis[y]||y==f)
continue;
getroot(y,x);
sz[x]+=sz[y];
maxp[x]=max(maxp[x],sz[y]);
}
maxp[x]=max(maxp[x],tsz-sz[x]);
if(maxp[x]<maxp[rt])
rt=x;
}
void dfs_calc(int x,int f,int dep,int dis)
{
if(dis>k)return;
if(t[k-dis]!=2139062143)
ans=min(ans,dep+t[k-dis]);
for(int i=head[x];i;i=nxt[i])
{
if(vis[y]||y==f)
continue;
dfs_calc(y,x,dep+1,dis+val[i]);
}
}
void dfs_put(int x,int f,int dep,int dis)
{
if(dis>k) return;
t[dis]=min(t[dis],dep);
for(int i=head[x];i;i=nxt[i])
{
if(y==f||vis[y])
continue;
dfs_put(y,x,dep+1,dis+val[i]);
}
}
void calc(int x)
{
t[0]=0;
for(int i=head[x];i;i=nxt[i])
{
if(vis[y])
continue;
dfs_calc(y,x,1,val[i]);
dfs_put(y,x,1,val[i]);
}
}
void divide(int x)
{
calc(x);
vis[x]=1;
for(int i=head[x];i;i=nxt[i])
{
if(vis[y])continue;
rt=0;
tsz=sz[y];
memset(t,0x3f,sizeof(t));
getroot(y,0);
divide(rt);
}
}
int main()
{
memset(t,0x3f,sizeof(t));
t[0]=0;
scanf("%d%d",&n,&k);
for(int i=1;i<n;i++)
{
int x,c,z;
scanf("%d%d%d",&x,&c,&z);
x++,c++;
add(x,c,z);
add(c,x,z);
}
rt=0;
maxp[0]=0x7f7f7f7f;
tsz=n;
getroot(1,0);
divide(rt);
if(ans==2139062143)
printf("-1\n");
else
printf("%d\n",ans);
return 0;
}