先求每个点的最远路,然后用RMQ维护队列求解。
ACcode:
#include<set>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MS=18;
const int NS=50010;
const int INF=1<<30;
const double eps=1e-8;
struct Edge{
int to,next,w;
}edge[NS<<1];
int n,m;
int fi[NS],se[NS];
int head[NS],top;
int bit[MS],lg[NS];
int up[NS][MS],dn[NS][MS];
void prepare()
{
for (int i=0;i<18;i++)
bit[i]=1<<i;
double t=log(2.0);
for (int i=1;i<NS;i++)
lg[i]=int(log(0.0+i)/t);
}
void add_edge(int u,int v,int w)
{
edge[top].w=w;
edge[top].to=v;
edge[top].next=head[u];
head[u]=top++;
}
void dfs1(int rt,int fa)
{
fi[rt]=se[rt]=0;
for (int i=head[rt];i!=-1;i=edge[i].next)
{
int to=edge[i].to,w=edge[i].w;
if (to!=fa)
{
dfs1(to,rt);
if (fi[to]+w>fi[rt])
{
se[rt]=fi[rt];
fi[rt]=fi[to]+w;
}else
if (fi[to]+w>se[rt])
{
se[rt]=fi[to]+w;
}
}
}
}
void dfs2(int rt,int fa)
{
for (int i=head[rt];i!=-1;i=edge[i].next)
{
int t,to=edge[i].to,w=edge[i].w;
if (to!=fa)
{
if (fi[to]+w==fi[rt])
t=se[rt];
else
t=fi[rt];
if (t+w>fi[to])
{
se[to]=fi[to];
fi[to]=t+w;
}else
if (t+w>se[to])
{
se[to]=t+w;
}
dfs2(to,rt);
}
}
}
void rmq()
{
for (int i=1;i<=n;i++)
up[i][0]=dn[i][0]=fi[i];
for (int j=1;j<MS;j++)
for (int i=1;i<=n;i++)
{
if (i+bit[j]>n+1) break;
up[i][j]=max(up[i][j-1],up[ i+bit[j-1] ][j-1]);
dn[i][j]=min(dn[i][j-1],dn[ i+bit[j-1] ][j-1]);
}
}
int judge(int x,int y)
{
int k=lg[y-x+1];
k=max(up[x][k],up[y-bit[k]+1][k])
-min(dn[x][k],dn[y-bit[k]+1][k]);
return k;
}
int cal(int x)
{
int l=1,r=1;
for (;r<=n;r++)
{
if (judge(l,r)>x)
break;
}
int ans=(r--)-l;
for (;r<=n;)
{
if (judge(l,r)>x)
l++;
else
{
r++;
ans=max(ans,r-l);
}
}
return ans;
}
int main()
{
prepare();
while(~scanf("%d%d",&n,&m),n+m)
{
top=0;
memset(head,-1,sizeof(head));
int x,y,z;
for (int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
dfs1(1,-1);
dfs2(1,-1);
rmq();
for (;m--;)
{
scanf("%d",&x);
printf("%d\n",cal(x));
}
}
return 0;
}