# BZOJ1468 Tree

  1 /**************************************************************
2     Problem: 1468
3     User: rausen
4     Language: C++
5     Result: Accepted
6     Time:756 ms
7     Memory:2528 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <algorithm>
12
13 using namespace std;
14 const int N = 40005;
15
16 struct edge {
17     int next, to, v;
18     edge() {}
19     edge(int _n, int _t, int _v) : next(_n), to(_t), v(_v) {}
20 } e[N << 1];
21
22 int first[N], tot;
23
24 struct tree_node {
25     int sz, dep;
26     bool vis;
27 } tr[N];
28
29 int n, k, ans;
30 int dep[N], cnt_dep;
31 int Root, Maxsz;
32
34     int x = 0;
35     char ch = getchar();
36     while (ch < '0' || '9' < ch)
37         ch = getchar();
38     while ('0' <= ch && ch <= '9') {
39         x = x * 10 + ch - '0';
40         ch = getchar();
41     }
42     return x;
43 }
44
45 void Add_Edges(int x, int y, int z) {
46     e[++tot] = edge(first[x], y, z), first[x] = tot;
47     e[++tot] = edge(first[y], x, z), first[y] = tot;
48 }
49
50 void dfs(int p, int fa, int sz) {
51     int x, y, maxsz = 0;
52     tr[p].sz = 1;
53     for (x = first[p]; x; x = e[x].next)
54         if ((y = e[x].to) != fa && !tr[y].vis) {
55             dfs(y, p, sz);
56             tr[p].sz += tr[y].sz;
57             maxsz = max(maxsz, tr[y].sz);
58         }
59     maxsz = max(maxsz, sz - tr[p].sz);
60     if (maxsz < Maxsz)
61         Root = p, Maxsz = maxsz;
62 }
63
64 int get_root(int p, int sz) {
65     Maxsz = N << 1;
66     dfs(p, 0, sz);
67     return Root;
68 }
69
70 void get_dep(int p, int fa) {
71     int x, y;
72     dep[++cnt_dep] = tr[p].dep;
73     for (x = first[p]; x; x = e[x].next)
74         if ((y = e[x].to) != fa && !tr[y].vis) {
75             tr[y].dep = tr[p].dep + e[x].v;
76             get_dep(y, p);
77         }
78 }
79
80 int cal(int p, int now) {
81     tr[p].dep = now, cnt_dep = 0;
82     get_dep(p, 0);
83     sort(dep + 1, dep + cnt_dep + 1);
84     int res = 0, l, r;
85     for (l = 1, r = cnt_dep; l < r; )
86         if (dep[l] + dep[r] <= k)
87             res += r - l, ++l;
88         else --r;
89     return res;
90 }
91
92 void work(int p, int sz) {
93     int root = get_root(p, sz), x, y;
94     ans += cal(root, 0);
95     tr[root].vis = 1;
96     for (x = first[root]; x; x = e[x].next)
97         if (!tr[y = e[x].to].vis) {
98             ans -= cal(y, e[x].v);
99             work(y, tr[p].sz);
100         }
101 }
102
103 int main() {
104     int i, x, y, z;
106     for (i = 1; i < n; ++i) {
114 }