码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1468 Tree 【模板】树上点分治

时间:2018-04-16 18:25:55      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:namespace   oid   AC   tchar   print   while   algorithm   color   read   

技术分享图片

技术分享图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #define N 50010
 4 #define M 500010
 5 #define rg register
 6 #define LL long long
 7 using namespace std;
 8 int n,m,cnt,root,tot,totnow,totbf;
 9 int last[N],size[N],mxsize[N],dep[N],tmp[N],mg[N];
10 LL ans=0;
11 bool v[N];
12 struct edge{
13     int to,pre,dis;
14 }e[M];
15 inline int read(){
16     int k=0,f=1; char c=getchar();
17     while(c<0||c>9)c==-&&(f=-1),c=getchar();
18     while(0<=c&&c<=9)k=k*10+c-0,c=getchar();
19     return k*f;
20 }
21 void getroot(int x,int fa){
22     size[x]=1; mxsize[x]=0;
23     for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]&&to!=fa){
24         getroot(to,x); size[x]+=size[to];
25         mxsize[x]=max(mxsize[x],size[to]);
26     }
27     mxsize[x]=max(mxsize[x],cnt-mxsize[x]);
28     if(!root||mxsize[x]<mxsize[root]) root=x;
29 }
30 void getdep(int x,int fa,int d){
31     dep[++totnow]=d;
32     for(rg int i=last[x],to;i;i=e[i].pre)
33         if(!v[to=e[i].to]&&to!=fa) getdep(to,x,d+e[i].dis);
34 }
35 void dfs(int x){
36     v[x]=1; totbf=1; tmp[1]=0;
37     for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]){
38         totnow=0; getdep(to,x,e[i].dis); sort(dep+1,dep+1+totnow);
39         int p=1;
40         for(rg int j=totbf;j;j--){
41             while(p<=totnow&&tmp[j]+dep[p]<=m) p++;
42             ans+=p-1;
43         }
44         p=1; int p2=1,totmg=0;
45         while(p<=totnow&&p2<=totbf) 
46             mg[++totmg]=dep[p]<tmp[p2]?dep[p++]:tmp[p2++];
47         while(p<=totnow) mg[++totmg]=dep[p++];
48         while(p2<=totbf) mg[++totmg]=tmp[p2++];
49         for(rg int j=1;j<=totmg;j++) tmp[j]=mg[j];
50         totbf=totmg;
51     }
52     for(rg int i=last[x],to;i;i=e[i].pre)if(!v[to=e[i].to]){
53         root=0; cnt=size[to];
54         getroot(to,x); dfs(root);
55     }
56 }
57 int main(){
58     n=read();
59     for(rg int i=1;i<n;i++){
60         int u=read(),v=read(),w=read();
61         e[++tot]=(edge){v,last[u],w}; last[u]=tot;
62         e[++tot]=(edge){u,last[v],w}; last[v]=tot;
63     }
64     m=read();
65     cnt=n; getroot(1,0); dfs(root);
66     printf("%lld\n",ans);
67 }
View Code

 

  

BZOJ 1468 Tree 【模板】树上点分治

标签:namespace   oid   AC   tchar   print   while   algorithm   color   read   

原文地址:https://www.cnblogs.com/DriverLao/p/8856425.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!