[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

HINT

三个月没碰点分治了复习一波,老年选手竟然还能打出来

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define inf 1e8
 6 #define ll long long
 7 #define M 40010
 8 using namespace std;
 9 struct point{
10     int next,to,dis;
11 }e[M<<1];
12 int head[M],dis[M],maxsize[M],size[M];
13 bool vis[M];
14 int n,num,k,S,maxn,root;
15 ll ans;
16 void add(int from,int to,int dis)
17 {
18     e[++num].next=head[from];
19     e[num].to=to;
20     e[num].dis=dis;
21     head[from]=num;
22 }
23 void getroot(int x,int fa)
24 {
25     size[x]=1; maxsize[x]=0;
26     for(int i=head[x];i;i=e[i].next)
27     {
28         int to=e[i].to;
29         if(vis[to]||to==fa) continue;
30         getroot(to,x);
31         maxsize[x]=max(maxsize[x],size[to]);
32         size[x]+=size[to];
33     }
34     maxsize[x]=max(S-size[x],maxsize[x]);
35     if(maxsize[x]<maxn) maxn=maxsize[x],root=x;
36 }
37 void getdis(int x,int fa,int len)
38 {
39     dis[++num]=len;
40     for(int i=head[x];i;i=e[i].next)
41     {
42         int to=e[i].to;
43         if(vis[to]||to==fa) continue;
44         getdis(to,x,len+e[i].dis);
45     }
46     return;
47 }
48 int cal(int x,int len)
49 {
50     num=0;
51     memset(dis,0,sizeof(dis));
52     getdis(x,0,len);
53     sort(dis+1,dis+1+num);
54     int l=1,r=num,tot=0;
55     while(l<=r)
56     {
57         if(dis[l]+dis[r]<=k) tot+=r-l,l++;
58         else r--; 
59     }
60     return tot;
61 }
62 void solve(int x)
63 {
64     ans+=cal(x,0);
65     vis[x]=true;
66     for(int i=head[x];i;i=e[i].next)
67     {
68         int to=e[i].to;
69         if(vis[to]) continue;
70         ans-=cal(to,e[i].dis);
71         S=size[to]; root=0; maxn=inf; 
72         getroot(to,0); solve(root);
73     }
74 }
75 int main()
76 {
77     scanf("%d",&n);
78     for(int i=1;i<=n-1;i++)
79     {
80         int x,y,z;
81         scanf("%d%d%d",&x,&y,&z);
82         add(x,y,z); add(y,x,z);
83     }
84     scanf("%d",&k);
85     maxn=inf; S=n; getroot(1,0);
86     solve(root);
87     printf("%lld",ans);
88     return 0;
89 }

猜你喜欢

转载自www.cnblogs.com/Slrslr/p/9383093.html
今日推荐