【模板·點分治】 洛谷 P3806 【模板】點分治1
阿新 • • 發佈:2018-12-24
題目:點分治
程式碼:
#include<bits/stdc++.h>
using namespace std;
#define maxn 10000
#define maxk 10000000
#define read(x) scanf("%d",&x)
struct Edge{
int y,z;
Edge(){}
Edge(int yy,int zz) {y=yy,z=zz;}
};
int n,m;
vector<Edge> a[maxn+5];
bool vis[maxn+5];
int rt,ms;
int sz[maxn+5],maxson[ maxn+5];
int SZ;
void readin() {
read(n),read(m);
for(int i=1;i<n;i++) {
int x,y,z;
read(x),read(y),read(z);
a[x].push_back(Edge(y,z));
a[y].push_back(Edge(x,z));
}
}
void getroot(int x,int fa) {
sz[x]=1,maxson[x]=0;
for(int i=0;i<a[x].size();i++) {
int y=a[x][i].y;
if(vis[y]|| y==fa) continue;
getroot(y,x);
sz[x]+=sz[y];
maxson[x]=max(maxson[x],sz[y]);
}
maxson[x]=max(maxson[x],SZ-sz[x]);
if(maxson[x]<ms) {
ms=maxson[x];
rt=x;
}
}
vector<int> dist;
int sum[maxk+5];
void getdis(int x,int fa,int z) {
dist.push_back(z);
for(int i=0;i<a[x].size(); i++) {
int y=a[x][i].y;
if(y==fa||vis[y]) continue;
getdis(y,x,z+a[x][i].z);
}
}
void slv(int x,int y,int ad) {
dist.clear();
getdis(x,0,y);
for(int i=0;i<dist.size()-1;i++) {
for(int j=i+1;j<dist.size();j++) {
sum[dist[i]+dist[j]]+=ad;
}
}
}
void fenzhi(int x) {
vis[x]=true;
slv(x,0,1);
for(int i=0;i<a[x].size();i++) {
int y=a[x][i].y;
if(vis[y]) continue;
slv(y,a[x][i].z,-1);
ms=1e9,rt=0,SZ=sz[y];
getroot(y,0);
fenzhi(rt);
}
}
int main() {
readin();
ms=1e9,SZ=n;
getroot(1,0);
fenzhi(rt);
while(m--) {
int x;
read(x);
if(sum[x]) printf("AYE\n");
else printf("NAY\n");
}
return 0;
}