数据结构(树,点分治):POJ 1741 Tree

时间:2024-12-28 17:36:08

Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001).
Define dist(u,v)=The min distance between node u and v.

Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.

Write a program that will count how many pairs which are valid for a given tree.

Input

The
input contains several test cases. The first line of each test case
contains two integers n, k. (n<=10000) The following n-1 lines each
contains three integers u,v,l, which means there is an edge between node
u and v of length l.

The last test case is followed by two zeros.

Output

For each test case output the answer on a single line.

Sample Input

5 4
1 2 3
1 3 1
1 4 2
3 5 1
0 0

Sample Output

8
  点分治模板……
 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=;
int cnt,n,k,N;
bool vis[maxn];
int fir[maxn],to[maxn<<],nxt[maxn<<],val[maxn<<];
void addedge(int a,int b,int v){
nxt[++cnt]=fir[a];fir[a]=cnt;val[cnt]=v;to[cnt]=b;
} int rt,sz[maxn],son[maxn];
int st[maxn],tot,dis[maxn];
void Get_RT(int x,int fa){
sz[x]=;son[x]=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa&&!vis[to[i]]){
Get_RT(to[i],x);
sz[x]+=sz[to[i]];
son[x]=max(sz[to[i]],son[x]);
}
son[x]=max(son[x],N-sz[x]);
if(!rt||son[rt]>son[x])rt=x;
} void DFS(int x,int fa){
st[++tot]=dis[x];
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa&&!vis[to[i]]){
dis[to[i]]=dis[x]+val[i];
DFS(to[i],x);
}
} int Calc(int x,int d){
int ret=;tot=;
dis[x]=d;DFS(x,);
sort(st+,st+tot+);
int l=,r=tot;
while(l<r){
if(st[l]+st[r]>k)r-=;
else {ret+=r-l;l+=;}
}
return ret;
} int Solve(int x){
vis[x]=true;
int ret=Calc(x,);
for(int i=fir[x];i;i=nxt[i])
if(!vis[to[i]]){
ret-=Calc(to[i],val[i]);
N=sz[to[i]];rt=;
Get_RT(to[i],);
ret+=Solve(rt);
}
return ret;
} int main(){
while(true){
scanf("%d%d",&n,&k);
if(!n&&!k)break;cnt=;N=n;
memset(vis,,sizeof(vis));
memset(fir,,sizeof(fir));
for(int i=,a,b,v;i<n;i++){
scanf("%d%d%d",&a,&b,&v);
addedge(a,b,v);addedge(b,a,v);
}
Get_RT(,);
printf("%d\n",Solve(rt));
}
return ;
}