poj1741 树分治
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 12000
int e[maxn],v[maxn*2],ne[maxn*2],w[maxn*2];
bool vis[maxn];
int n;
int nn;
void add(int x,int y,int z){
nn++;
ne[nn]=e[x];
e[x]=nn;
v[nn]=y;
w[nn]=z;
}
void clear(){
nn=0;
memset(vis,0,sizeof(vis));
memset(e,0,sizeof(e));
}
int tot,a[maxn];
int dist[maxn],siz[maxn];
void dfs1(int x,int fa){
a[++tot]=dist[x];
for(int i=e[x];i;i=ne[i]){
if(v[i]==fa||vis[v[i]])continue;
dist[v[i]]=dist[x]+w[i];
dfs1(v[i],x);
}
}
int cc[maxn],k;
int bn,b[maxn];
void dfs2(int x,int fa){
siz[x]=1;
cc[x]=0;
b[++bn]=x;
for(int i=e[x];i;i=ne[i]){
if(fa==v[i]||vis[v[i]])continue;
dfs2(v[i],x);
cc[x]=max(cc[x],siz[v[i]]);
siz[x]+=siz[v[i]];
}
}
int count(int x,int ma){
if(ma<=0)return 0;
tot=0;
dist[x]=0;
dfs1(x,0);
sort(a+1,a+tot+1);
int bo=tot;
int res=0;
for(int i=1;i<=tot;i++){
while(a[i]+a[bo]>ma&&bo>i)bo--;
if(bo>i)res+=bo-i;
}
return res;
}
int ans;
int pp;
void solv(int x){
int rt=-1;
bn=0;
dfs2(x,0);
if(bn==1)return;
for(int i=1;i<=bn;i++){
cc[b[i]]=max(cc[b[i]],bn-siz[b[i]]);
if(rt==-1||cc[b[i]]<cc[rt])rt=b[i];
}
ans+=count(rt,k);
vis[rt]=1;
for(int i=e[rt];i;i=ne[i])if(!vis[v[i]]){
ans-=count(v[i],k-2*w[i]);
solv(v[i]);
}
}
int main(){
while(scanf("%d%d",&n,&k)&&(n!=0||k!=0)){
clear();
ans=0;
for(int i=1;i<n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
solv(1);
printf("%d\n",ans);
}
}