[poj1741]Tree
点分治入门。。

1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 using namespace std; 8 9 const int N=100000; 10 int h[N],r[N],to[N],w[N],tot,n,k,root,ans,sz[N],f[N],dep[N],d[N],v[N],num,sum; 11 void insert(int u,int v,int z){ 12 to[tot]=v; 13 r[tot]=h[u]; 14 w[tot]=z; 15 h[u]=tot++; 16 } 17 void ins(int u,int v,int z){insert(u,v,z);insert(v,u,z);} 18 19 void GR(int x,int fa){ 20 sz[x]=1;f[x]=0; 21 for(int i=h[x];i!=-1;i=r[i]){ 22 if(to[i]!=fa&&!v[to[i]]){ 23 GR(to[i],x); 24 sz[x]+=sz[to[i]]; 25 f[x]=max(f[x],sz[to[i]]); 26 } 27 } 28 f[x]=max(f[x],sum-sz[x]); 29 if(f[x]<f[root])root=x; 30 } 31 32 void DP(int x,int f){ 33 dep[++num]=d[x]; 34 for(int i=h[x];i!=-1;i=r[i]){ 35 if(to[i]!=f&&!v[to[i]]){ 36 d[to[i]]=d[x]+w[i]; 37 DP(to[i],x); 38 } 39 } 40 } 41 42 int C(int x,int y,int t=0){ 43 d[x]=y; 44 num=0; 45 DP(x,0); 46 sort(dep+1,dep+1+num); 47 for(int l=1,r=num;l<r;){ 48 if(dep[l]+dep[r]<=k){t+=r-l;l++;} 49 else r--; 50 } 51 return t; 52 } 53 void W(int x){ 54 ans+=C(x,0); 55 v[x]=1; 56 for(int i=h[x];i!=-1;i=r[i]){ 57 if(!v[to[i]]){ 58 ans-=C(to[i],w[i]); 59 sum=sz[to[i]]; 60 root=0; 61 GR(to[i],root); 62 W(root); 63 } 64 } 65 } 66 int main(){ 67 while(scanf("%d%d",&n,&k)==2&&(n||k)){ 68 memset(h,-1,sizeof(h)); 69 memset(v,0,sizeof(v)); 70 ans=0; 71 root=0; 72 tot=0; 73 for(int i=1,u,v,z;i<n;i++){ 74 scanf("%d%d%d",&u,&v,&z); 75 ins(u,v,z); 76 } 77 f[0]=0x3f3f3f3f; 78 sum=n; 79 GR(1,0); 80 W(root); 81 printf("%d\n",ans); 82 } 83 }