The main idea of a tree's point division is to find the center of gravity of the subtree, calculate the number of cases through the root node, and subtract the case of the point pair belonging to the same subtree.
1#include <iostream>2#include <vector>3#include <algorithm>4#include <string>5#include <string.h>6#include <stdio.h>7#include <stdlib.h>8#include <queue>9#include <stack>Ten#include <map> One#include <Set> A#include <cmath> -#include <ctime> -#include <cassert> the#include <sstream> - using namespacestd; - - Const intn=10010; + structEdge { - intTo,next; + intW; A Edge () {} atEdge (int_t,int_n,int_w=0) { -to=_t; -next=_n; -w=_w; - } -}edge[n<<1]; in intIdx,head[n]; - voidAddedge (intUintVintW) { to++idx; +edge[idx]=Edge (v,head[u],w); -head[u]=idx; the } * BOOLVis[n]; $ Panax Notoginseng intK//the k in the input - the intdis[n],discnt; + voidGetdis (intUintFintd) { Adis[discnt++]=D; the for(intk=head[u];k;k=Edge[k].next) { + intv=edge[k].to; - if(vis[v]| | V==F)Continue; $Getdis (v,u,d+EDGE[K].W); $ } - } - the intbal,cmp; - intGetbal (intUintf) {Wuyi intson=1; the intdp=0; - for(intk=head[u];k;k=Edge[k].next) { Wu intv=edge[k].to; - if(vis[v]| | V==F)Continue; About intsubson=Getbal (v,u); $son+=Subson; -dp=Max (Dp,subson); - } -Dp=max (dp,discnt-son); A if(dp<CMP) { +cmp=DP; theBal=u; - } $ returnSon; the } the the intCalcintUintInitdis) { theDiscnt=0; -Getdis (u,-1, Initdis); inSort (dis,dis+discnt); the intret=0; the intL=0, r=discnt-1; About while(l<r) { the if(dis[l]+dis[r]>k) r--; the Elseret+=r-l++; the } + returnret; - } the Bayi intans=0; the voidSolveintu) { thecmp=~0U>>1; -Getbal (u,-1); -Ans+=calc (Bal,0); thevis[bal]=true; the for(intk=head[bal];k;k=Edge[k].next) { the intv=edge[k].to; the if(Vis[v])Continue; -Ans-=calc (V,EDGE[K].W);//subtract from repeated calculations within a subtree the solve (v); the } the }94 the voidInitintN) { theidx=1; Memset (Head,0,sizeofhead); thememset (Vis,false,sizeofvis);98Discnt=n;//because when calculating the center of gravity, it is possible to directly use the discnt when the dis was calculated, so this is initialized to n Aboutans=0; - }101 intMain () {102 intN;103 while(SCANF ("%d%d", &n,&k)! =EOF) {104 if(n==0&&k==0) Break; the init (n);106 for(intI=1; i<n;i++) {107 intu,v,w;108scanf" %d%d%d",&u,&v,&W);109 Addedge (u,v,w); the Addedge (v,u,w);111 } theSolve1);113printf"%d\n", ans); the } the return 0; the}
The point division of POJ 1741/1987 Tree