给一棵树,问树上长度为k的路径是否存在。
点分治核心就是对于经过根节点的路径dfs求解,对于不经过根节点的路径分治求解(在子树上分治)。
//
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimization ("unroll-loops")
//
//#pragma GCC optimize(3,"Ofast","inline")
//#include<unordered_map>
//#include<unordered_set>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
#include<vector>
#include<sstream>
#include<list>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
int mod=104857601;
const int maxn=2e6+5;
int head[maxn],q[110],siz[maxn],maxp[maxn],tmp[maxn],dis[maxn];
bool ans[110],judje[maxn*100],vis[maxn];
int num,root,sum,cnt;
int n,m;
struct node
{
int v,w,next;
}e[maxn];
void add(int u,int v,int w)
{
e[num]={v,w,head[u]};
head[u]=num++;
}
void dfs(int u,int f)
{
maxp[u]=0;siz[u]=1;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(v==f||vis[v])continue ;
dfs(v,u);
maxp[u]=max(maxp[u],siz[v]);
siz[u]+=siz[v];
}
maxp[u]=max(maxp[u],sum-siz[u]);
if(maxp[root]>maxp[u])root=u;
}
void getdis(int u,int f)
{
tmp[cnt++]=dis[u];
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(v==f||vis[v])continue;
dis[v]=dis[u]+e[i].w;
getdis(v,u);
}
}
void solve(int u)
{
queue<int>que;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
cnt=0;
dis[v]=e[i].w;
getdis(v,u);
for(int j=0;j<cnt;j++)
for(int k=1;k<=m;k++)
if(q[k]>=tmp[j])
ans[k]|=judje[q[k]-tmp[j]];
for(int j=0;j<cnt;j++)
{
que.push(tmp[j]);
judje[tmp[j]]=true;
}
}
while(!que.empty())
{
judje[que.front()]=0;
que.pop();
}
}
void divide(int u)
{
vis[u]=judje[0]=1;
solve(u);
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
maxp[root=0]=sum=siz[v];
dfs(v,0);
dfs(root,0);
divide(root);
}
}
int main()
{
memset(head,-1,sizeof head);
cin>>n>>m;
for(int i=1;i<n;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
for(int i=1;i<=m;i++)cin>>q[i];
maxp[0]=sum=n;
dfs(1,0);
dfs(root,0);
divide(root);
for(int i=1;i<=m;i++)
{
if(ans[i])cout<<"AYE"<<endl;
else cout<<"NAY"<<endl;
}
return 0;
}