最近不造应该干什么好,很快就STOI了,好慌>.<
裸点分治,找树的重心然后处理
1 //#include<bits/stdc++.h> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 #include<queue> 7 #define inc(i,l,r) for(int i=l;i<=r;i++) 8 #define dec(i,l,r) for(int i=l;i>=r;i--) 9 #define link(x) for(edge *j=h[x];j;j=j->next) 10 #define mem(a) memset(a,0,sizeof(a)) 11 #define inf 1e9 12 #define ll long long 13 #define succ(x) (1<<x) 14 #define lowbit(x) (x&(-x)) 15 #define NM 10000+5 16 using namespace std; 17 int read(){ 18 int x=0,f=1;char ch=getchar(); 19 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 20 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 21 return x*f; 22 } 23 struct edge{ 24 int t,v; 25 edge *next; 26 }e[2*NM],*h[NM],*o; 27 void add(int x,int y,int v){ 28 o->t=y;o->v=v;o->next=h[x];h[x]=o++; 29 } 30 int n,ans,root,k,l,r,smin,num,d[NM],size[NM],_x,_y,_t; 31 bool v[NM]; 32 void count(int x,int f){ 33 size[x]=1; 34 link(x)if(j->t!=f&&!v[j->t]) 35 count(j->t,x),size[x]+=size[j->t]; 36 } 37 void gfind(int x,int f){ 38 int s=num-size[x]; 39 link(x)if(j->t!=f&&!v[j->t]) 40 s=max(s,size[j->t]),gfind(j->t,x); 41 if(s<smin)smin=s,root=x; 42 } 43 void dfs(int x,int f,int dis){ 44 d[++r]=dis; 45 link(x)if(j->t!=f&&!v[j->t])dfs(j->t,x,dis+j->v); 46 } 47 int cal(int x,int dis){ 48 int s=0;r=0;mem(d); 49 dfs(x,0,dis); 50 sort(d+1,d+1+r); 51 for(l=1;l<r;s+=r-l,l++) 52 while(d[l]+d[r]>k&&l<r)r--; 53 return s; 54 } 55 void div(int x){ 56 count(x,0); 57 smin=inf;num=size[x]; 58 gfind(x,0); 59 v[root]++; 60 ans+=cal(root,0); 61 link(root)if(!v[j->t]) 62 ans-=cal(j->t,j->v),div(j->t); 63 } 64 int main(){ 65 // freopen("data.in","r",stdin); 66 while(scanf("%d%d",&n,&k)&&(n||k)){ 67 mem(v);mem(h);mem(e);o=e;ans=0; 68 inc(i,1,n-1){ 69 _x=read();_y=read();_t=read();add(_x,_y,_t);add(_y,_x,_t); 70 } 71 div(1); 72 printf("%d\n",ans); 73 } 74 return 0; 75 }