Topic: https://www.luogu.org/problem/P3806
Meaning of the questions: a tree, here are the q ask, ask whether there is a point of distance k
Ideas: involves tree path problems are usually dotted rule, we can calculate the length of the path and then all preserved, dotted rule has been nothing more than a few steps recursive, dotted rule is recursive in the trees
1, find the center of gravity tree
2, calculate the center of gravity from all points to find the center of gravity of all current legal path
3, the sub-tree recursively
Then repeated this three-step
In fact, the only place in dotted rule is to solve the thinking function, the other is the same
https://www.cnblogs.com/guoshaoyang/p/10994997.html
https://www.cnblogs.com/PinkRabbit/p/8593080.html
#include <bits / STDC ++ H.> #define MAXN 100005 #define MOD 1,000,000,007 the using namespace STD; typedef Long Long LL; Vector <pair <LL, LL>> MP [MAXN]; // save enough FIG BOOL VIS [MAXN] ; // numerals have been used gravity LL MAXSIZE [MAXN], DIS [MAXN], D [MAXN]; // MAXSIZE largest subtree of the current node LL SIZ [MAXN], E [MAXN]; // DIS to the center of gravity the distance d from appeared LL n-, m, rt, SUM, QE; // distance subtree of the current node number siz e rt represents the current center of gravity occurring void find (X LL, LL F) { // find gravity SIZ [X] = . 1 ; MAXSIZE [X] = 0 ; for ( int I = 0 ; I <MP [X] .size (); I ++ ) { pair <LL, LL> Q = MP [X] [I]; IF (= q.first VIS || F = [q.first]) Continue ; // VIS array tags have used gravity Find (q.first, X); SIZ [X] + = SIZ [q.first]; MAXSIZE [X] = max (MAXSIZE [X], SIZ [q.first]); } MAXSIZE [X] = max (MAXSIZE [X], SUM-SIZ [X]); // total number of nodes by subtracting the current number of the current subtree = is the root node of the tree the number of father idea IF (MAXSIZE [X] < MAXSIZE [RT]) { RT = X; } } void get_dis(ll x,ll f,ll len){//得到每个点到重心的距离 if(len<=1e7){ e[++qe]=len; } for(int i=0;i<mp[x].size();i++){ pair<ll,ll> q=mp[x][i]; if(q.first==f||vis[q.first]) continue; dis[q.first]=dis[x]+len; get_dis(q.first,x,len+q.second); } } void solve(ll x,ll len,ll w){ qe=0; dis[x]=len; get_dis(x,0,len); for(int i=1;i<=qe;i++){ for(int j=1;j<=qe;j++){ if(i!=j){ d[e[i]+e[j]]+=w; } } } } void divide(ll x){//循环执行三步 solve(x,0,1); vis[x]=1; for(int i=0;i<mp[x].size();i++){ pair<ll,ll> q=mp[x][i]; if(vis[q.first]) continue; solve(q.first,q.second,-1); sum=siz[q.first]; rt=0; maxsize[rt]=mod; find(q.first,x); divide(rt); } } int main(){ cin>>n>>m; ll a,b,c; for(int i=0;i<n-1;i++){ cin>>a>>b>>c; mp[a].push_back(make_pair(b,c)); mp[b].push_back(make_pair(a,c)); } sum=n;//当前节点数 rt=0; maxsize[0]=mod;//置初值 find(1,0); divide(rt); while(m--){ cin>>a; if(d[a]){ printf("AYE\n"); } else{ printf("NAY\n"); } } }