1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
#include <algorithm> #include <cstring> using namespace std; int middis[40010],midcnt,n,k,u[40010<<1],v[40010<<1],w[40010<<1],cnt,fir[40010],nxt[40010<<1],sz[40100],f[40100],root,vis[40100],Siz; long long ans=0; void (int ui,int vi,int wi){ ++cnt; u[cnt]=ui; v[cnt]=vi; w[cnt]=wi; nxt[cnt]=fir[ui]; fir[ui]=cnt; } void findroot(int u,int fa){ f[u]=1; sz[u]=1; for(int i=fir[u];i;i=nxt[i]){ if(v[i]==fa||vis[v[i]]) continue; findroot(v[i],u); sz[u]+=sz[v[i]]; f[u]=max(f[u],sz[v[i]]); } f[u]=max(Siz-f[u],f[u]); if(f[root]>f[u]) root=u; } void getdis(int u,int d,int fa){ middis[++midcnt]=d; for(int i=fir[u];i;i=nxt[i]){ if(v[i]==fa||vis[v[i]]) continue; getdis(v[i],d+w[i],u); } } int look(int l,int k){ int ans=0,r=midcnt; while(l<=r){ int mid=(l+r)>>1; if(middis[mid]<=k) ans=mid,l=mid+1; else r=mid-1; } } int solve(int u,int d,int fa){ midcnt=0; getdis(u,d,fa); sort(middis+1,middis+midcnt+1); int l=1,ans=0; while(l<midcnt&&k-middis[l]>=middis[l]){ int lx=look(l+1,k-middis[l]); if(lx>l) ans+=lx-l-1; l++; } return ans; } void divide(int u){ vis[u]=true; ans+=solve(u,0,0); for(int i=fir[u];i;i=nxt[i]){ if(vis[v[i]]) continue; ans-=solve(v[i],w[i],u); root=0; Siz=sz[v[i]]; findroot(v[i],u); divide(root); } } int main(){ scanf("%d",&n); for(int i=1;i<=n-1;i++){ int a,b,c; scanf("%d %d %d",&a,&b,&c); addedge(a,b,c); addedge(b,a,c); } scanf("%d",&k); Siz=n; f[0]=0x3f3f3f3f; findroot(1,0); divide(root); printf("%dn",ans); return 0; }
|
近期评论