bzoj 1468 Tree 点分

Tree

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

Description

给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K

Input

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

Output

一行,有多少对点之间的距离小于等于k

Sample Input

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

Sample Output

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;
10 inline int read()
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));
84     n=read();
85     for (int i=1;i<n;i++)
86     {
87         int x=read(),y=read(),z=read();
88         add(x,y,z);
89         add(y,x,z);
90     }
91     k=read();
92     total=n,f[0]=inf;
93     get_heart(1,-1);
94     solve(id);
95     printf("%d\n",ans);
96 }

 

 
posted @ 2018-04-14 20:33  Kaiser-  阅读(85)  评论(0编辑  收藏  举报