【模板】点分治
洛谷 3806
1 #include<cstdio> 2 #include<algorithm> 3 #define N 10010 4 #define rg register 5 using namespace std; 6 int n,m,tot,cnt,root,last[N],siz[N],mxsiz[N],dep[N],q[N]; 7 bool have[10000010],ans[110],v[N]; 8 struct edge{ 9 int to,pre,dis; 10 }e[N<<2]; 11 inline int read(){ 12 int k=0,f=1; char c=getchar(); 13 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 14 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 15 return k*f; 16 } 17 void getroot(int x,int fa){ 18 siz[x]=1; 19 for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]&&to!=fa){ 20 getroot(to,x); 21 siz[x]+=siz[to]; mxsiz[x]=max(mxsiz[x],siz[to]); 22 } 23 mxsiz[x]=max(mxsiz[x],cnt-siz[x]); 24 if(!root||mxsiz[x]<mxsiz[root]) root=x; 25 } 26 void getdep(int x,int fa,int d){ 27 dep[tot++]=d; 28 for(rg int i=last[x],to;i;i=e[i].pre) 29 if(!v[to=e[i].to]&&to!=fa) getdep(to,x,d+e[i].dis); 30 } 31 void dfs(int x){ 32 v[x]=1; int l=tot=1; have[0]=1; 33 for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]){ 34 l=tot; getdep(to,x,e[i].dis); 35 for(rg int j=1;j<=m;j++){ 36 if(ans[j]) continue; 37 for(rg int k=l;k<tot;k++)if(q[j]>=dep[k]&&have[q[j]-dep[k]]){ 38 ans[j]=1; break; 39 } 40 } 41 for(rg int j=l;j<tot;j++) have[dep[j]]=1; 42 } 43 for(rg int i=1;i<tot;i++) have[dep[i]]=0; 44 for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]){ 45 cnt=siz[to]; root=0; getroot(to,x); dfs(root); 46 } 47 } 48 int main(){ 49 n=read(); m=read(); 50 for(rg int i=1;i<n;i++){ 51 int u=read(),v=read(),w=read(); 52 e[++tot]=(edge){v,last[u],w}; last[u]=tot; 53 e[++tot]=(edge){u,last[v],w}; last[v]=tot; 54 } 55 for(rg int i=1;i<=m;i++) q[i]=read(); 56 root=0; cnt=n; getroot(1,0); dfs(root); 57 for(rg int i=1;i<=m;i++) puts(ans[i]?"AYE":"NAY"); 58 return 0; 59 }