#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=10005;
struct node
{
int v, l;
node() {};
node(int _v, int _l): v(_v), l(_l) {};
};
vector<node> edge[2*maxn];
int n,k,root,s[maxn],f[maxn],all_size,rs[maxn],ans,cnt,tp[maxn],dist[maxn];
void init()
{
for(int i=0;i<=n;i++)
edge[i].clear();
memset(f,0,sizeof(f));
root=0;
rs[0]=all_size=n;
ans=0;
}
void read_tree()
{
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back(node(v,w));
edge[v].push_back(node(u,w));
}
}
void get_root(int now,int fa)
{
s[now]=1;
rs[now]=0;
for(vector<node>::iterator it=edge[now].begin();it!=edge[now].end();it++)
{
int to=it->v;
if(to!=fa&&!f[to])
{
get_root(to,now);
s[now]+=s[to];
rs[now]=max(rs[now],s[to]);
}
}
rs[now]=max(rs[now],all_size-s[now]);
if(rs[now]<rs[root])
root=now;
}
void get_depth(int now,int fa)
{
tp[cnt++]=dist[now];
s[now]=1;
for(vector<node>::iterator it=edge[now].begin();it!=edge[now].end();it++)
{
int to=it->v;
if(to!=fa&&!f[to])
{
dist[to]=dist[now]+it->l;
get_depth(to,now);
s[now]+=s[to];
}
}
}
int work(int now,int init_dist)
{
int res=0;
cnt=0;
dist[now]=init_dist;
get_depth(now,0);
sort(tp,tp+cnt);
for(int l=0,r=cnt-1;l<r;)
if(tp[l]+tp[r]<=k)
res+=r-l++;
else
r--;
return res;
}
void solve(int now)
{
ans+=work(now,0);
f[now]=1;
for(vector<node>::iterator it=edge[now].begin();it!=edge[now].end();it++)
{
int to=it->v;
if(!f[to])
{
ans-=work(to,it->l);
f[0]=all_size=s[to];
get_root(to,root=0);
solve(root);
}
}
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF&&(n||k))
{
init();
read_tree();
get_root(1,root=0);
solve(root);
printf("%d\n",ans);
}
return 0;
}
poj 1741 树分治
最新推荐文章于 2019-05-07 15:13:29 发布