​题目传送门​

点分治:我的理解就是对树进行分治,再对这棵树的每棵子树进行分治,一直这样下去,当然树的根不是随便都可以的,以树的重心为根,复杂度会大大降低(个人拙见)。

代码:

#include<bits/stdc++.h>
using namespace std;

const int INF=0x3f3f3f3f;
const int maxn=10000+100;
const int maxm=10000000+100;

bool kaven[maxm],vis[maxn];
struct Edge{

int to,len,next;
}edge[maxn<<1];
int head[maxn],tot;
int son[maxn],dis[maxn];
int root,all,num;
int n,m;
struct Node{

int id,dis;
}node[maxn];
int Id,nodenum;

void Add(int u,int v,int len){

edge[tot].to=v;
edge[tot].len=len;
edge[tot].next=head[u];
head[u]=tot++;

edge[tot].to=u;
edge[tot].len=len;
edge[tot].next=head[v];
head[v]=tot++;
}
//得到目前这棵树的重心
void DFS(int u,int fa){

son[u]=1;
int maxson=0;
for(int i=head[u];i!=-1;i=edge[i].next){

Edge e=edge[i];
int v=e.to;
if(v==fa || vis[v]) continue;
son[u]+=son[v];
maxson=max(maxson,son[v]);
}
maxson=max(maxson,all-son[u]);
if(maxson<num) root=u,num=maxson;
}

//计算结点到当前树 root 的距离 (以前进行过点分治的除外,不然会有大量重复计算)
void getDis(int rot,int u,int fa,int id){

for(int i=head[u];i!=-1;i=edge[i].next){

Edge e=edge[i];
int v=e.to,len=e.len;
if(vis[v] || v==fa) continue;
dis[v]=dis[u]+len;
if(rot==u) node[nodenum].dis=dis[v],node[nodenum++].id= ++Id; //root的孩子结点是 root这棵树的子树的根,所以++Id 对子树根进行编号
else node[nodenum].dis=dis[v],node[nodenum++].id= id; //子树非根结点编号为子树根结点的编号
kaven[dis[v]]=true;
if(rot==u) getDis(rot,v,u,Id);
else getDis(rot,v,u,id);
}
}

//点分治
void getNode(int u){

dis[u]=0;
vis[u]=true;
Id=nodenum=0; //Id:对树根为 root 的每棵子树进行编号(以前进行过点分治的除外),在同一棵子树上的结点编号相同
getDis(root,u,-1,0);
for(int i=0;i<nodenum;i++){

for(int j=i+1;j<nodenum;j++){

if(node[i].id!=node[j].id) kaven[node[i].dis+node[j].dis]=true; //不同子树结点之间的距离
}
}
for(int i=head[u];i!=-1;i=edge[i].next){

Edge e=edge[i];
int v=e.to;
if(vis[v]) continue;
root=0;all=son[v];num=INF; //初始化
DFS(v,-1); //找子树的重心
getNode(root); //子树进行点分治
}
}

int main(){

scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) head[i]=-1;
tot=0;root=0;num=INF;all=n;
for(int i=1;i<n;i++){

int u,v,len;
scanf("%d%d%d",&u,&v,&len);
Add(u,v,len);
}
DFS(1,-1);
getNode(root);
for(int i=1,k;i<=m;i++) scanf("%d",&k),printf("%s\n",kaven[k]?"AYE":"NAY");
}