1. 程式人生 > >【模板·點分治】 洛谷 P3806 【模板】點分治1

【模板·點分治】 洛谷 P3806 【模板】點分治1

題目:點分治

程式碼:

#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; }