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.
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.
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
点分治模板……
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 const int maxn=10010; 7 int cnt,n,k,N; 8 bool vis[maxn]; 9 int fir[maxn],to[maxn<<1],nxt[maxn<<1],val[maxn<<1]; 10 void addedge(int a,int b,int v){ 11 nxt[++cnt]=fir[a];fir[a]=cnt;val[cnt]=v;to[cnt]=b; 12 } 13 14 int rt,sz[maxn],son[maxn]; 15 int st[maxn],tot,dis[maxn]; 16 void Get_RT(int x,int fa){ 17 sz[x]=1;son[x]=0; 18 for(int i=fir[x];i;i=nxt[i]) 19 if(to[i]!=fa&&!vis[to[i]]){ 20 Get_RT(to[i],x); 21 sz[x]+=sz[to[i]]; 22 son[x]=max(sz[to[i]],son[x]); 23 } 24 son[x]=max(son[x],N-sz[x]); 25 if(!rt||son[rt]>son[x])rt=x; 26 } 27 28 void DFS(int x,int fa){ 29 st[++tot]=dis[x]; 30 for(int i=fir[x];i;i=nxt[i]) 31 if(to[i]!=fa&&!vis[to[i]]){ 32 dis[to[i]]=dis[x]+val[i]; 33 DFS(to[i],x); 34 } 35 } 36 37 int Calc(int x,int d){ 38 int ret=0;tot=0; 39 dis[x]=d;DFS(x,0); 40 sort(st+1,st+tot+1); 41 int l=1,r=tot; 42 while(l<r){ 43 if(st[l]+st[r]>k)r-=1; 44 else {ret+=r-l;l+=1;} 45 } 46 return ret; 47 } 48 49 int Solve(int x){ 50 vis[x]=true; 51 int ret=Calc(x,0); 52 for(int i=fir[x];i;i=nxt[i]) 53 if(!vis[to[i]]){ 54 ret-=Calc(to[i],val[i]); 55 N=sz[to[i]];rt=0; 56 Get_RT(to[i],0); 57 ret+=Solve(rt); 58 } 59 return ret; 60 } 61 62 int main(){ 63 while(true){ 64 scanf("%d%d",&n,&k); 65 if(!n&&!k)break;cnt=0;N=n; 66 memset(vis,0,sizeof(vis)); 67 memset(fir,0,sizeof(fir)); 68 for(int i=1,a,b,v;i<n;i++){ 69 scanf("%d%d%d",&a,&b,&v); 70 addedge(a,b,v);addedge(b,a,v); 71 } 72 Get_RT(1,0); 73 printf("%d ",Solve(rt)); 74 } 75 return 0; 76 }