【BZOJ1468】Tree

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
 
又是一道点分治的题,方法同聪聪可可。
 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N=40010;
 5 int deep[N],head[N],son[N],f[N],d[N],root,ans,n,sum,cnt,k;
 6 bool vis[N];
 7 struct ee{int to,next,w;}e[N*2];
 8 void insert(int u,int v,int w){
 9     e[++cnt].to=v;e[cnt].next=head[u];e[cnt].w=w;head[u]=cnt;
10 }
11  
12 void getroot(int x,int fa){
13     son[x]=1;f[x]=0;
14     for (int i=head[x];i;i=e[i].next){
15         int v=e[i].to;
16         if (vis[v]||v==fa) continue;
17         getroot(v,x);
18         son[x]+=son[v];
19         f[x]=max(f[x],son[v]);
20     }
21     f[x]=max(f[x],sum-f[x]);
22     if (f[x]<f[root]) root=x;
23 }
24  
25 void getdeep(int x,int fa){
26     deep[++deep[0]]=d[x];
27     for (int i=head[x];i;i=e[i].next){
28         int v=e[i].to;
29         if (vis[v]||v==fa) continue;
30         d[v]=d[x]+e[i].w;
31         getdeep(v,x);
32     }
33 }
34  
35 int cal(int x,int now){
36     int t=0;
37     d[x]=now;deep[0]=0;
38     getdeep(x,0);
39     sort(deep+1,deep+deep[0]+1);
40     int l=1,r=deep[0];
41     for (;l<r;) if (deep[l]+deep[r]<=k){t+=r-l;l++;}
42                 else r--;
43     return t;
44 }
45  
46 void work(int x){
47     ans+=cal(x,0);
48     vis[x]=1;
49     for (int i=head[x];i;i=e[i].next){
50         int v=e[i].to;
51         if (!vis[v]) {
52             ans-=cal(v,e[i].w);sum=son[v];root=0;
53             getroot(v,0);
54             work(root);
55         }
56     }
57 }
58  
59 int main(){
60     scanf("%d",&n);
61     int u,v,w;
62     for (int i=1;i<n;i++){
63         scanf("%d%d%d",&u,&v,&w);
64         insert(u,v,w);
65         insert(v,u,w);
66     }
67     f[0]=sum=n;
68     scanf("%d",&k);
69     getroot(1,0);
70     work(root);
71     printf("%d",ans); 
72 }

 

posted @ 2016-01-18 21:45  Alisahhh  阅读(162)  评论(0编辑  收藏  举报