Topic: https://vjudge.net/contest/307753#problem/B
Meaning of the questions: Determining the tree path = k and of the existence of
Ideas: point divide and conquer, and in fact this question on a topic, like Luo Valley, but this data is strong, we can not pre-direct all possible path length, the path length of the pre-treatment of all complexity O (n ^ 2), we changed direct every query partition again, as long as we seek to solve it in O (n), that time complexity is O (n * logn * logn) , a lot faster on time, in fact, equal to k this before you can use our method. K is not greater than the direct path - path less than k = k is equal to the path, and then engage in a practice it
#include <cstdio> #include <CString> #include <the cmath> #include <algorithm> #include <the iostream> #include <Vector> #define MAXN 100005 #define MOD 1E19 the using namespace STD; typedef Long Long LL; LL DA; Vector <pair <LL, LL>> MP [MAXN]; // save enough FIG BOOL VIS [MAXN]; // tag have used gravity LL MAXSIZE [MAXN], DIS [MAXN], D [MAXN]; / / largest subtree of the current node maxsize LL SIZ [MAXN], E [MAXN]; // DIS distance to the center of gravity d distance appeared n-LL, m, rt, SUM, QE; // distance e siz number subtree of the current node appears rt represents the current focus void Find (X LL, LL F) { // find the center of 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 || F VIS == [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 = subtree rooted at the current node number father idea tree IF (MAXSIZE [X] < MAXSIZE [RT]) { RT = X; } } void get_dis (X LL, F LL, LL len) { 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); } } ll solve(ll x,ll len){ ll ee=0; qe=0; dis[x]=len; get_dis(x,0,len); sort(e+1,e+qe+1); ll l=1,r=qe; while(l<r){ if(e[l]+e[r]<=m){ ee+=r-l; l++; } else{ r--; } } return ee; } void divide(ll x){ da+=solve(x,0); vis[x]=1; for(int i=0;i<mp[x].size();i++){ pair<ll,ll> q=mp[x][i]; if(vis[q.first]) continue; da-=solve(q.first,q.second); sum=siz[q.first]; rt=0; maxsize[rt]=mod; find(q.first,x); divide(rt); } } void init(){ da=0; for(int i=0;i<=n;i++) mp[i].clear(); for(int i=0;i<=n;i++) vis[i]=0; } int main(){ while(scanf("%lld%lld",&n,&m)!=EOF) { if(n==0&&m==0) break; ll a,b,c; init(); char s[5]; for(int i=0;i<n-1;i++){ scanf("%lld%lld%lld%s",&a,&b,&c,s); //a++; //b++; mp[a].push_back(make_pair(b,c)); mp[b].push_back(make_pair(a,c)); } scanf("%lld",&m); sum=n;//当前节点数 rt=0; maxsize[0]=mod;//置初值 find(1,0); divide(rt); printf("%lld\n",da); } }