The complexity of normal DFS access for each point pair is O (n^2), which obviously times out.
When considering access to the root node of the current subtree, statistics all the points passing through the root (U, v) meet:
Dist (U) + dist (v) <= Maxd, and
Belong (u) ≠belong (v) (that is, u,v is not in the same subtree).
The distance referred to here refers to the distance from the node to the heel.
Can be used as the subtraction method, which subtracts the point logarithm of the son node of the root node from the node of the current subtree, using all the point logarithms that satisfy the condition.
The above step can be solved with the complexity of O (Nlogn), that is, sorting before comparing.
The root node tree can be solved recursively, with the point of the tree.
The upper bound of total complexity is O (NLOGNLOGN).
http://poj.org/problem?id=1987
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 Const intMAXN = 1e5 +Ten;6 Const intINF =0x3f3f3f3f;7 structedge{8 intto, Next, W;9}EDGE[MAXN <<1];Ten intHEAD[MAXN], N; One intN, M, Maxd; A BOOLVIS[MAXN]; - intCNT[MAXN]; - intMAXI[MAXN]; the intans; - intMini, root, sum; - intBUF[MAXN], K; - + voidAddedge (intUintVintW) { -Edge[n].next =Head[u]; +Edge[n].to =v; AEDGE[N].W =W; atHead[u] = n++; - } - - voidinit () { -N =0; -Memset (Head,-1,sizeofhead); in } - to voidGET_CNT (intu) { +Cnt[u] =1; -Vis[u] =1; theMaxi[u] =-1; *buf[k++] =u; $ for(inti = Head[u]; i +1; i =Edge[i].next) {Panax Notoginseng intv =edge[i].to; - if(Vis[v])Continue; the get_cnt (v); +Cnt[u] + =Cnt[v]; AMaxi[u] =Max (Maxi[u], cnt[v]); the } +Vis[u] =0; - } $ $ voidGet_dist (intUintd) { -Vis[u] =1; -buf[k++] =D; the for(inti = Head[u]; i +1; i =Edge[i].next) { - intv =edge[i].to;Wuyi if(Vis[v])Continue; theGet_dist (V, D +EDGE[I].W); - } WuVis[u] =0; - } About $ intGet_buf_sum (intLeftintRight ) { -Sort (buf + left, buf +Right ); - intTEM =0; - for(inti = right-1, j = left; I >= left +1; i--){ A while(J < i && Buf[i] + buf[j] <= maxd) + +J; +Tem + = min (i, j)-Left ; the } - returntem; $ } the the voidCalintu) { theK =0; the get_cnt (u); -Mini =inf; in for(inti =0; I < K; i++){ the intTEM = MAX (Cnt[u]-Cnt[buf[i]], maxi[buf[i]); the if(TEM < mini) Mini = tem, root =Buf[i]; About } theK =0; theVis[root] =1; the intTEM =0; + for(inti = Head[root]; i +1; i =Edge[i].next) { - intv =edge[i].to; the if(Vis[v])Continue;Bayi intPre =K; the get_dist (v, EDGE[I].W); theTEM-=Get_buf_sum (pre, k); - } -buf[k++] =0; theTEM + = Get_buf_sum (0, k); theAns + =tem; the for(inti = Head[root]; i +1; i =Edge[i].next) { the intv =edge[i].to; - if(Vis[v])Continue; the Cal (v); the } the }94 the voidsolve () { thescanf"%d", &maxd); thememset (Vis,0,sizeofvis);98Ans =0; About for(inti =1; I <= N; i++){ - if(!Vis[i]) cal (i);101 }102printf"%d\n", ans);103 }104 the intMain () {106 //freopen ("In.txt", "R", stdin);107 while(~SCANF ("%d", &N)) {108scanf"%d", &m);109 init (); the for(inti =0, x, Y, Z; I < m; i++){111scanf"%d%d%d", &x, &y, &z); the Addedge (x, y, z);113 Addedge (y, x, z); the GetChar (), GetChar (); the } the solve ();117 }118 return 0;119}
View Code
poj1987 Distance Statistics