# bzoj1468

## 1468: Tree

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1023  Solved: 532
[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

## Source

点分治裸题，那么什么是点分治呢

点分治

1、求树的重心
2、计算以当前重心为根的子树的答案
3、去掉以当前重心儿子为根的子树的答案
4、枚举每个儿子，分治

 1 #include<iostream>
2 #include<cstring>
3 #include<cstdio>
4 #include<algorithm>
5 #include<cmath>
6 #define maxn 40005
7 using namespace std;
8 int n,k,i,j,tot,root,ans,L,all;
9 int pre[maxn*2],now[maxn],v[maxn*2],val[maxn*2],son[maxn],f[maxn];
10 int dist[maxn],data[maxn];
11 bool vis[maxn];
13 {
14     int x=0; char ch; bool bo=0;
15     while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1;
16     while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
17     if (bo) return -x; return x;
18 }
19 void ins(int a,int b,int c){
20     pre[++tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c;
21 }
22 void get_root(int u,int fa)
23 {
24     son[u]=1; f[u]=0;
25     for (int p=now[u]; p; p=pre[p])
26     {
27         int vv=v[p];
28         if (vv==fa || vis[vv]) continue;
29         get_root(vv,u); son[u]+=son[vv];
30         f[u]=max(f[u],son[vv]);
31     }
32     f[u]=max(f[u],all-son[u]);
33     if (f[u]<f[root]) root=u;
34 }
35 void get_array(int u,int fa)
36 {
37     data[++L]=dist[u];
38     for (int p=now[u]; p; p=pre[p])
39     {
40         int vv=v[p];
41         if (vv!=fa&&!vis[vv])
42         dist[vv]=dist[u]+val[p],get_array(vv,u);
43     }
44 }
45 int calc(int u,int value)
46 {
47     dist[u]=value; L=0; get_array(u,-1);
48     sort(data+1,data+1+L);
49     int preans=0,l=1,r=L;
50     while (l<r)
51     {
52         if (data[l]+data[r]<=k) preans+=(r-l),l++; else r--;
53     }
54     return preans;
55 }
56 void solve(int u)
57 {
58     ans+=calc(u,0); vis[u]=1;
59     //cout<<"        ans       "<<u<<endl;
60     for (int p=now[u]; p; p=pre[p])
61     {
62         int vv=v[p];
63         //cout<<"                   "<<vv<<endl;
64         if (vis[vv]) continue;
65         ans-=calc(vv,val[p]); f[root=0]=n+1;
66         all=son[vv]; get_root(vv,-1);
67         solve(root);
68     }
69 }
70 int main()
71 {
73     for (int i=1; i<=n-1; i++)
74     {
76         ins(u,v,value); ins(v,u,value);
77     }
79     f[root=0]=n+1; all=n;
80     get_root(1,-1);
81     //cout<<"                "<<root<<endl;
82     solve(root);
83     printf("%d\n",ans);
84     return 0;
85 }
View Code

posted @ 2016-05-07 20:31  ACist  阅读(176)  评论(0编辑  收藏  举报