Test instructions: Give you a tree, ask the path and how many of the paths are multiples of 3
Ideas: Daily handling points, the problem is actually used to take the mold, three of the multiple can actually be converted to 3 modulo, and then direct Point Division
Code: (Always T, finally found that it was getroot when written wrong)
#include <cstdio>#include<cstring>#include<algorithm>using namespacestd;intRead () {intx=0, w=1;CharCh=GetChar (); while((ch<'0'|| Ch>'9') &&ch!='-') ch=GetChar (); if(ch=='-') w=0, ch=GetChar (); while(ch>='0'&&ch<='9') x= (x<<3) + (x<<1) +ch-'0', ch=GetChar (); returnw?x:-x;}Const intmaxn=20005;structedge{intTo,next,w;} A[MAXN<<1];intn,m,k,head[maxn],cnt;intROOT,SUM,VIS[MAXN],SZ[MAXN];intF[MAXN],DEP[MAXN];intans;intt[5];intMAX (intXinty) { returnX>y?x:y;}intgcdintXinty) { returny==0? X:GCD (y,x%y);}voidAddedge (intUintVintW) {a[++cnt].to=v; A[cnt].next=Head[u]; A[CNT].W=W; Head[u]=CNT;}voidGetroot (intUintFA) {Sz[u]=1; f[u]=0; for(intE=head[u];e;e=A[e].next) { intv=a[e].to;if(v==fa| | VIS[V])Continue; Getroot (V,u); Sz[u]+=Sz[v]; F[u]=MAX (F[u],sz[v]); } F[u]=max (f[u],sum-Sz[u]); if(F[u]<f[root]) root=u;}voidGetdeep (intUintFA) {T[dep[u]%3]++; for(intE=head[u];e;e=A[e].next) { intv=a[e].to;if(v==fa| | VIS[V])Continue; DEP[V]=dep[u]+A[E].W; Getdeep (V,u); }}intCalcintUintD0) {Dep[u]=d0;t[0]=t[1]=t[2]=0; Getdeep (U,0); returnt[0]*t[0]+2*t[1]*t[2];}voidSolveintu) {ans+=calc (U,0); vis[u]=1; for(intE=head[u];e;e=A[e].next) { intv=a[e].to;if(Vis[v])Continue; Ans-=Calc (V,A[E].W); Sum=sz[v];root=0; Getroot (V,0); Solve (root); }}intMain () {n=read (); for(intI=1; i<n;++i) { intU=read (), V=read (), w=read (); Addedge (U,V,W); Addedge (V,U,W); } f[0]=sum=N; Getroot (1,0); Solve (root); int as=GCD (ans,n*N); Ans/= as; printf ("%d/%d\n", ans,n*n/ as); return 0;}
P2634 [National training team] Cong Cocoa (point division)