题意:
给一棵树,有边权。问边权和<=k的路径有多少条。
解法:
TreeDp+分治。漆子超的论文。。
const int N = 1e4 + 9;
int n , k , ans;
struct EDGE{
int to , len , next;
}edge[N << 1];
int head[N] , tot;
void addedge(int u , int v , int len){
edge[tot].to = v;
edge[tot].len = len;
edge[tot].next = head[u];
head[u] = tot++;
}
int sons[N] , core , corecnt;
int dis[N];
int lis[N] , listot;
bool vis[N];
void coredfs(int u , int v){ // Count the Sons
sons[u] = 1;
int ret = 1;
for(int i = head[u] ; i != -1 ; i = edge[i].next){
int go = edge[i].to;
if (go == v || vis[go]) continue;
coredfs(go , u);
sons[u] += sons[go];
}
}
void coreedit(int u , int v , int cnt){ //Find core
int ret = 1;
for(int i = head[u] ; i != -1 ; i = edge[i].next){
int go = edge[i].to;
if (go == v || vis[go]) continue;
coreedit(go , u , cnt);
checkMax(ret , sons[go]);
}
checkMax(ret , cnt - sons[u]);
if (ret < corecnt){
core = u;
corecnt = ret;
}
}
int Qcore(int u){ // Subtree's Core
corecnt = INF;
coredfs(u , 0);
coreedit(u , 0 , sons[u]);
return core;
}
void rushDis(int u , int len , int v){
lis[listot++] = len;
for (int i = head[u] ; i != -1 ; i = edge[i].next){
int g = edge[i].to;
if (g != v && !vis[g]) rushDis(g , len + edge[i].len , u);
}
}
int calc(int u , int len){
int ret = 0;
listot = 0;
rushDis(u , len , 0);
sort(lis , lis + listot);
int head = 0 , tail = listot - 1;
while(head < tail){
while(head < tail && lis[head] + lis[tail] > k) tail--;
ret += tail - head;
head++;
}
return ret;
}
void dfs(int u){ //Treedp the subtree of Root-u
Qcore(u);
ans += calc(core , 0);
vis[core] = 1;
for (int i = head[core] ; i != -1 ; i = edge[i].next){
int g = edge[i].to;
if (!vis[g]){
ans -= calc(g , edge[i].len);
dfs(g);
}
}
}
void solve(){
tot = 0;
FLC(head , -1);
REP(i , n - 1){
int u , v , w;
RD(u , v , w);
addedge(u , v , w);
addedge(v , u , w);
}
ans = 0;
RST(vis);
dfs(1);
OT(ans);
}
int main(){
// freopen("0.txt" , "r" , stdin);
// freopen("1.txt" , "w" , stdout);
while(RD(n , k) , n && k) solve();
}