# bzoj 1468 Tree 点分

## Tree

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1972  Solved: 1101
[Submit][Status][Discuss]

## Input

N（n<=40000） 接下来n-1行边描述管道，按照题目中写的输入 接下来是k

7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10

5

## HINT

题解：点分模板题
 1 #include<cstring>
2 #include<algorithm>
3 #include<iostream>
4 #include<cstdio>
5 #include<cmath>
6
7 #define N 40007
8 #define inf 1000000007
9 using namespace std;
11 {
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
15     return x*f;
16 }
17
18 int n,k,ans,id,total;
19 int cnt,hed[N],rea[N<<1],nxt[N<<1],val[N<<1];
20 int tot,num[N],siz[N],f[N];
21 bool vis[N];
22
23 void add(int u,int v,int z)
24 {
25     nxt[++cnt]=hed[u];
26     hed[u]=cnt;
27     rea[cnt]=v;
28     val[cnt]=z;
29 }
30 void get_heart(int u,int fa)
31 {
32     siz[u]=1,f[u]=0;
33     for (int i=hed[u];i!=-1;i=nxt[i])
34     {
35         int v=rea[i];
36         if (v==fa||vis[v]) continue;
37         get_heart(v,u);
38         siz[u]+=siz[v];
39         f[u]=max(f[u],siz[v]);
40     }
41     f[u]=max(f[u],total-f[u]);
42     if (f[u]<f[id]) id=u;
43 }
44 void dfs_dep(int u,int now,int fa)
45 {
46     num[++tot]=now;
47     for (int i=hed[u];i!=-1;i=nxt[i])
48     {
49         int v=rea[i],fee=val[i];
50         if (v==fa||vis[v]) continue;
51         dfs_dep(v,now+fee,u);
52     }
53 }
54 int calc(int u,int now)
55 {
56     tot=0;int res=0;
57     dfs_dep(u,now,0);
58     sort(num+1,num+tot+1);
59     int l=1,r=tot;
60     while(l<r)
61     {
62         if (num[l]+num[r]<=k) res+=r-l,l++;
63         else r--;
64     }
65     return res;
66 }
67 void solve(int u)
68 {
69     ans+=calc(u,0);
70     vis[u]=true;
71     for (int i=hed[u];i!=-1;i=nxt[i])
72     {
73         int v=rea[i],fee=val[i];
74         if (vis[v]) continue;
75         ans-=calc(v,fee);
76         total=siz[v],id=0;
77         get_heart(v,u);
78         solve(v);
79     }
80 }
81 int main()
82 {
83     memset(hed,-1,sizeof(hed));
85     for (int i=1;i<n;i++)
86     {
96 }