# BZOJ1468 Tree

#include <cstdio>
#include <cstring>
#include <algorithm>

#define N 50010
#define LL long long

using namespace std;

struct edge{
int x,to,v;
}E[N<<1];

int n,g[N],K,totE,ansv;

inline void addedge(int x,int y,int v){
E[++totE]=(edge){y,g[x],v}; g[x]=totE;
E[++totE]=(edge){x,g[y],v}; g[y]=totE;
}

#define p E[i].x

namespace Tree_Dc{
int siz[N],root,f[N],totn,a[N],d[N],tot;
bool v[N];

void Find_Hea(int x,int ft){
siz[x]=1; f[x]=0;
for(int i=g[x];i;i=E[i].to)
if(ft!=p&&!v[p]){
Find_Hea(p,x);
siz[x]+=siz[p];
f[x]=max(f[x],siz[p]);
}
f[x]=max(f[x],totn-siz[x]);
if(!root||f[x]<f[root])
root=x;
}

inline int Root(int x){
root=0; totn=siz[x];
Find_Hea(x,x);
return root;
}

void dfs(int x,int ft){
a[++tot]=d[x];
for(int i=g[x];i;i=E[i].to)
if(!v[p]&&p!=ft){
d[p]=d[x]+E[i].v;
dfs(p,x);
}
}

inline int count_path(int x,int v){
d[x]=v; tot=0;
dfs(x,0);
sort(a+1,a+tot+1);
int ans=0,tmp=1;
for(int i=2;i<=tot;i++){
while(tmp<i&&a[i]+a[tmp+1]<=K) tmp++;
while(tmp&&a[i]+a[tmp]>K) tmp--;
ans+=min(tmp,i-1);
}
return ans;
}

void DC(int x){
int tmp=ansv;
ansv+=count_path(x,0);
v[x]=1;
for(int i=g[x];i;i=E[i].to)
if(!v[p]){
ansv-=count_path(p,E[i].v);
DC(Root(p));
}
}
}

int main(){
freopen("test.in","r",stdin);
scanf("%d",&n);
for(int i=1,x,y,v;i<n;i++){
scanf("%d%d%d",&x,&y,&v);
}
scanf("%d",&K);
Tree_Dc::siz[1]=n;
Tree_Dc::DC(Tree_Dc::Root(1));
printf("%d\n",ansv);
return 0;
}
Code

posted @ 2015-06-03 15:28  lawyer'  阅读(126)  评论(0编辑  收藏  举报