点分治
- 点分治的分治中心是重心,所以先要会找重心
找重心
void getroot(int u,int fa)
{
sim[u]=1;mxson[u]=0;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].v;
int w=edge[i].w;
if(vis[v]||v==fa) continue;
getroot(v,u);
sim[u]+=sim[v];
mxson[u]=max(mxson[u],sim[v]);
}
mxson[u]=max(mxson[u],smer-sim[u]);
if(mxson[u]<MX)
{
MX=mxson[u];root=u;
}
}
- sim[i]是以i为根的节点数(不包含他father那一部分)
mxson[i]是以i为根的树中(smer范围内)最大子树
root为重心 - 开始分治,分治时注意去掉两个点在同一子树的重复
code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int read() {
int x=0,f=1;char ch=' ';
while(ch<'0'||ch>'9'){ if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int N=10100;
const int inf=0x3f3f3f3f;
struct node
{
int v,nxt,w;
}edge[N<<1];
int head[N],cnt;
void add(int u,int v,int w)
{
cnt++;
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
}
bool vis[N];
int sim[N],mxson[N];
int MX,smer,root;
void getroot(int u,int fa)
{
sim[u]=1;mxson[u]=0;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].v;
int w=edge[i].w;
if(vis[v]||v==fa) continue;
getroot(v,u);
sim[u]+=sim[v];
mxson[u]=max(mxson[u],sim[v]);
}
mxson[u]=max(mxson[u],smer-sim[u]);
if(mxson[u]<MX)
{
MX=mxson[u];root=u;
}
}
int cc;
int dis[N];
void dfs(int u,int fa,int k)
{
dis[++cc]=k;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].v;
int w=edge[i].w;
if(vis[v]||v==fa) continue;
dfs(v,u,k+w);
}
}
int ans[10000100];
void solve(int u,int w,int x)
{
cc=0;
memset(dis,0,sizeof(dis));
dfs(u,0,w);
sort(dis+1,dis+1+cc);
for(int i=1;i<=cc;i++)
{
for(int j=1;j<=cc;j++)
{
if(i!=j)
{
ans[dis[i]+dis[j]]+=x;
}
}
}
}
void divide(int u)
{
solve(u,0,1);
vis[u]=true;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].v;
int w=edge[i].w;
if(vis[v]) continue;
solve(v,w,-1);
smer=sim[v];root=0;
MX=inf;getroot(v,0);
divide(root);
}
}
int main()
{
int n,m;
n=read();m=read();
int i,j;
for(i=1;i<n;i++)
{
int a,b,c;
a=read();b=read();c=read();
add(a,b,c);
add(b,a,c);
}
MX=inf;smer=n;
getroot(1,0);
divide(root);
while(m--)
{
int k=read();
if(ans[k]) cout<<"AYE"<<endl;
else cout<<"NAY"<<endl;
}
return 0;
}