算法流程:找到树的重心,删去这个点,递归子树。
题号luogu3806
#include <iostream>
#include <ctime>
#include <algorithm>
#include <windows.h>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=10005;
inline int read(){
int k=0,f=1; char c=getchar();
while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
return k*f;
}
int n,m,K,siz[N],head[N],ecnt,size,rt,cnt,a[150],f[N];
struct Edge{int to,nxt,val;}e[N<<1];
struct Node{int from,val; bool operator < (const Node &rhs) const {return val<rhs.val;};};
bool vis[N],ans[106];
Node dis[10005];
void add(int bg,int ed,int val){(++ecnt)[e].to=ed;ecnt[e].val=val;ecnt[e].nxt=bg[head];bg[head]=ecnt;}
int binary(int x) {
int l=1,r=cnt,ans=0;
while(l<=r) {
int mid=l+r>>1;
if(dis[mid].val<x) l=mid+1;
else r=mid-1,ans=mid;
}
return ans;
}
void barycenter(int x,int fa) {
f[x]=0,siz[x]=1;
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(vis[v]||fa==v) continue;
barycenter(v,x);
f[x]=max(f[x],siz[v]);
siz[x]+=siz[v];
}
f[x]=max(f[x],size-siz[x]);
if(f[x]<f[rt]) rt=x;
}
void dfs(int x,int fa,int from,int val) {
dis[++cnt]={from,val};
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;
if(vis[v]||fa==v) continue;
dfs(v,x,from,val+e[i].val);
}
}
void work(int x) {
cnt=0;
for(int i=x[head];i;i=i[e].nxt ) {
int v=i[e].to;
if(v[vis]) continue;
dfs(v,x,v,e[i].val);
}
(++cnt)[dis]={0,0};
sort(dis+1,dis+1+cnt);
for(int i=1;i<=m;i++) {
if(i[ans]) continue;
int l=1;
while(l<cnt&&a[i]>(dis[l].val+dis[cnt].val)) l++;
while(l<cnt&&!ans[i]) {
if(a[i]-dis[l].val<dis[l].val) break;
int pos=binary(a[i]-dis[l].val);
while(dis[pos].val+dis[l].val==a[i]&&l<=cnt&&dis[pos].from==dis[l].from) pos++;
if(dis[pos].val+dis[l].val==a[i]) ans[i]=1;
l++;
}
}
}
void solve(int x) {
vis[x]=1;
work(x);
for(int i=head[x];i;i=e[i].nxt) {
int v=e[i].to;rt=0;
if(v[vis]) continue;
siz[rt]=size=siz[v];
barycenter(v,0);
solve(rt);
}
}
int main() {
int st=clock();
n=read();m=read();
for(int i=1,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z),add(y,x,z);
for(int i=1;i<=m;i++) a[i]=read();
f[rt]=size=n;
barycenter(1,0);
solve(rt);
for(int i=1;i<=m;i++)puts(ans[i]?"AYE":"NAY");
int ed=clock();
Sleep(200);
cout<<ed-st;
return 0;
}