点分治模板

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<cstring>
 7 #define PAU putchar(' ')
 8 #define ENT putchar('\n')
 9 using namespace std;
10 const int maxn=100000+10,inf=-1u>>1;
11 struct tedge{int x,y,w,next;}adj[maxn<<1];int fch[maxn],ms=0;
12 void addedge(int u,int v,int w){
13     adj[++ms]=(tedge){u,v,w,fch[u]};fch[u]=ms;
14     adj[++ms]=(tedge){v,u,w,fch[v]};fch[v]=ms;
15     return;
16 }
17 int deep[maxn],d[maxn],f[maxn],son[maxn],n,K,cnt,sum,ans,root;bool vis[maxn];
18 void getroot(int x,int fa){
19     son[x]=1;f[x]=0;
20     for(int i=fch[x];i;i=adj[i].next){
21         int v=adj[i].y;
22         if(v==fa||vis[v])continue;
23         getroot(v,x);
24         son[x]+=son[v];
25         f[x]=max(f[x],son[v]);
26     }
27     f[x]=max(f[x],sum-son[x]);
28     if(f[x]<f[root])root=x;return;
29 }
30 void getdeep(int x,int fa){
31     deep[++deep[0]]=d[x];
32     for(int i=fch[x];i;i=adj[i].next){
33         int v=adj[i].y;
34         if(v==fa||vis[v])continue;
35         d[v]=d[x]+adj[i].w;
36         getdeep(v,x);
37     } return;
38 }
39 int cal(int x,int now){
40     d[x]=now;deep[0]=0;getdeep(x,0);
41     sort(deep+1,deep+deep[0]+1);
42     int t=0,l,r;
43     for(l=1,r=deep[0];l<r;){
44         if(deep[l]+deep[r]<=K){t+=r-l;l++;}
45         else r--;
46     } return t;
47 }
48 void work(int x){
49     ans+=cal(x,0);vis[x]=1;
50     for(int i=fch[x];i;i=adj[i].next){
51         int v=adj[i].y;
52         if(vis[v])continue;
53         ans-=cal(v,adj[i].w);
54         sum=son[v];
55         root=0;
56         getroot(v,root);
57         work(root);
58     } return;
59 }
60 inline int read(){
61     int x=0,sig=1;char ch=getchar();
62     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
63     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
64     return x*=sig;
65 }
66 inline void write(int x){
67     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
68     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
69     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
70 }
71 int main(){
72     while(1){
73         ans=0;root=0;cnt=0;
74         memset(vis,0,sizeof(vis));
75         memset(fch,0,sizeof(fch));
76         n=read();K=read();
77         if(n==0)break;
78         for(int i=1;i<n;i++){
79             int u=read(),v=read(),w=read();
80             addedge(u,v,w);
81         }
82         sum=n;f[0]=inf;
83          getroot(1,0);
84         work(root);
85         write(ans);ENT;
86     } return 0;
87 }

 

posted @ 2015-06-21 14:53  AI_Believer  阅读(141)  评论(0编辑  收藏  举报