# Tree

 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 21357 Accepted: 7006

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

Source

1、经过根节点

2、不经过根节点，也就是说在根节点的一棵子树中

 1 #include <iostream>
2 #include <cstdio>
3 #include <cmath>
4 #include <cstring>
5 #include <vector>
6 #include <algorithm>
7 using namespace std;
8 const int N = 1e5+20, M = 1e2+10, mod = 1e9+7, inf = 1e9+1000;
9 typedef long long ll;
10
12 int deep[N];//路径长度//deep[0]子节点个数
13 int f[N];//重心
14
15 struct edg{int to,next,v;}e[N * 4];//前向星存边
17
18 //获取重心
19 void getroot(int x,int fa) {
20     siz[x] = 1;
21     f[x] = 0;
23         int to = e[i].to;
24         if(to == fa || vis[to]) continue;
25         getroot(to,x);
26         siz[x] += siz[to];
27         f[x] = max(f[x] , siz[to]);
28     }
29     f[x] = max(allnode-siz[x] , f[x]);
30     if(f[x] < f[root]) root = x;
31 }
32
33 void getdeep(int x,int fa) {//获取子树所有节点与根的距离
34     deep[++deep[0]] = d[x];
36         int to = e[i].to;
37         if(to == fa || vis[to]) continue;
38         d[to] = d[x] + e[i].v;
39         getdeep(to,x);
40     }
41 }
42 int cal(int x,int now) {//计算当前以重心x的子树下，所有情况的答案
43     d[x]=now;deep[0]=0;
44     getdeep(x,0);
45     sort(deep+1,deep+deep[0]+1);
46     int all = 0;
47     for(int l=1,r=deep[0];l<r;) {
48         if(deep[l]+deep[r] <= K) {all += r-l;l++;}
49         else r--;
50     }
51     return all;
52 }
53
54 void work(int x) {//以x为重心进行计算
55     vis[x] = 1;
56     ans+=cal(x,0);
58         int to = e[i].to;
59         if(vis[to]) continue;
60         ans -= cal(to,e[i].v);
61         allnode = siz[to];
62         root=0;
63         getroot(to,x);
64         work(root);
65     }
66 }
67
68 int main()
69 {
70     while(~scanf("%d%d",&n,&K)) {
71         if(!n&&!m) break;
73         memset(vis,0,sizeof(vis));
74         t = 1;
75         for(int i=1;i<n;i++) {
76             int a,b,c;
77             scanf("%d%d%d",&a,&b,&c);
79         }
80         root=ans=0;
81         allnode=n;f[0]=inf;
82         getroot(1,0);
83         work(root);
84         printf("%d\n",ans);
85     }
86 }

posted @ 2017-03-25 22:41 Angel_Kitty 阅读(...) 评论(...) 编辑 收藏
Live2D