点分模板题
都快改的跟题解一模一样了2333333
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 struct E 6 { 7 int to,nxt,d; 8 }e[20100]; 9 int f1[10100],ne; 10 bool vis[10100]; 11 int n,k,root,sz[10100],fx[10100],sum,ans; 12 //sum:当前连通块节点总数 13 int dep[10100],tmp[10100]; 14 void getroot(int x,int fa) 15 //获取x所在连通块内的根 16 { 17 sz[x]=1;fx[x]=0; 18 for(int k=f1[x];k;k=e[k].nxt) 19 if(!vis[e[k].to]&&e[k].to!=fa) 20 { 21 getroot(e[k].to,x); 22 sz[x]+=sz[e[k].to]; 23 fx[x]=max(fx[x],sz[e[k].to]); 24 } 25 fx[x]=max(fx[x],sum-sz[x]); 26 if(fx[x]<fx[root]) root=x; 27 } 28 void getsz(int x,int fa) 29 //处理出当前连通块的大小 30 { 31 sz[x]=1; 32 for(int k=f1[x];k;k=e[k].nxt) 33 if(!vis[e[k].to]&&e[k].to!=fa) 34 { 35 getsz(e[k].to,x); 36 sz[x]+=sz[e[k].to]; 37 } 38 } 39 void getdeep(int u,int fa) 40 { 41 tmp[++tmp[0]]=dep[u]; 42 for(int k=f1[u];k;k=e[k].nxt) 43 if(!vis[e[k].to]&&e[k].to!=fa) 44 { 45 dep[e[k].to]=dep[u]+e[k].d; 46 getdeep(e[k].to,u); 47 } 48 } 49 int cal(int u,int cost) 50 { 51 dep[u]=cost;tmp[0]=0; 52 getdeep(u,0); 53 sort(tmp+1,tmp+tmp[0]+1); 54 int l,r,sum=0; 55 r=tmp[0]+1; 56 for(l=1;l<=tmp[0];l++) 57 { 58 while(r>1&&tmp[r-1]>k-tmp[l]) r--; 59 if(l>=r) break; 60 sum+=(r-l-1); 61 } 62 return sum; 63 } 64 void solve(int u) 65 //解决u所在连通块的问题,u作为该块的根 66 { 67 ans+=cal(u,0);vis[u]=1; 68 for(int k=f1[u];k;k=e[k].nxt) 69 if(!vis[e[k].to]) 70 { 71 ans-=cal(e[k].to,e[k].d); 72 root=0; 73 getsz(e[k].to,0);sum=sz[e[k].to]; 74 getroot(e[k].to,0); 75 solve(root); 76 } 77 } 78 int main() 79 { 80 int i,u,v,l; 81 fx[0]=0x3f3f3f3f; 82 while(1) 83 { 84 memset(f1,0,sizeof(f1));ne=ans=0; 85 memset(vis,0,sizeof(vis)); 86 scanf("%d%d",&n,&k); 87 if(n==0&&k==0) break; 88 for(i=1;i<n;i++) 89 { 90 scanf("%d%d%d",&u,&v,&l); 91 e[++ne].to=v;e[ne].nxt=f1[u];e[ne].d=l;f1[u]=ne; 92 e[++ne].to=u;e[ne].nxt=f1[v];e[ne].d=l;f1[v]=ne; 93 } 94 sum=n; 95 getroot(1,0); 96 solve(root); 97 printf("%d ",ans); 98 } 99 return 0; 100 }