点分治
看懂了。照着hzw(%打了一遍
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define rep(i,n) for(int i=1;i<=n;i++) #define clr(x,c) memset(x,c,sizeof(x)) #define adde(u,v,d) add(u,v,d),add(v,u,d) #define qwq(x) for(node *o=head[x];o;o=o->next) int read(){ int x=0;char c=getchar();bool f=true; while(!isdigit(c)){ if(c=='-') f=false;c=getchar(); } while(isdigit(c)) x=x*10+c-'0',c=getchar(); return f?x:-x; } const int nmax=10005; const int inf=0x7f7f7f7f; struct node{ int to,d;node*next; }; node e[nmax<<1],*pt=e,*head[nmax]; int f[nmax],deep[nmax],d[nmax],son[nmax]; bool vis[nmax]; int sum,n,k,ans,root; void add(int u,int v,int d){ pt->to=v;pt->d=d;pt->next=head[u];head[u]=pt++; } void getroot(int x,int fa){ son[x]=1;f[x]=0; qwq(x){ if(o->to!=fa&&!vis[o->to]){ getroot(o->to,x);son[x]+=son[o->to]; f[x]=max(f[x],son[o->to]); } } f[x]=max(f[x],sum-son[x]); if(f[x]<f[root]) root=x; } void getdeep(int x,int fa){ deep[++deep[0]]=d[x]; qwq(x){ if(o->to!=fa&&!vis[o->to]){ d[o->to]=d[x]+o->d;getdeep(o->to,x); } } } int cal(int x,int now){ d[x]=now;deep[0]=0; getdeep(x,0);sort(deep+1,deep+deep[0]+1); int tmp=0; for(int l=1,r=deep[0];l<r;){ if(deep[l]+deep[r]<=k) tmp+=r-l,l++; else r--; } return tmp; } void work(int x){ ans+=cal(x,0);vis[x]=1; qwq(x){ if(vis[o->to]) continue; ans-=cal(o->to,o->d); sum=son[o->to];root=0; getroot(o->to,root);work(root); } } int main(){ while(1){ n=read(),k=read();if(n==0) break; clr(vis,0);clr(head,0);ans=root=0;pt=e; rep(i,n-1){ int s=read(),t=read(),w=read();adde(s,t,w); } sum=n;f[0]=inf;getroot(1,0);work(root); printf("%d\n",ans); } return 0; }