1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include<bits/stdc++.h> using namespace std; #define ll long long const int N = 2e4+10; struct edge{ int v,w,nex; edge(){} edge(int v,int w,int nex):v(v),w(w),nex(nex){} }edges[N<<1]; int siz[N],maxp[N]; int head[N],tot,vis[N],sum,rt,dis[N],tmp[4],cnt,ans; int gcd(int a,int b){ return b?gcd(b,a%b):a; } void add(int u,int v,int w){ edges[tot]=edge(v,w,head[u]); head[u]=tot++; } void getrt(int u,int fa){ siz[u]=1,maxp[u]=0; for(int i=head[u];~i;i=edges[i].nex){ int v = edges[i].v; if(vis[v]||v==fa)continue; getrt(v,u); siz[u]+=siz[v]; if(maxp[u]<siz[v])maxp[u]=siz[v]; } maxp[u]=max(maxp[u],sum-siz[u]); if(maxp[u]<maxp[rt])rt=u; } void getdis(int u,int fa){ tmp[dis[u]]++; for(int i=head[u];~i;i=edges[i].nex){ int v = edges[i].v; if(vis[v]||v==fa)continue; dis[v]=(dis[u]+edges[i].w)%3; getdis(v,u); } } int calc(int u,int v){ dis[u]=v%3; tmp[0]=tmp[1]=tmp[2]=0; getdis(u,0); return tmp[1]*tmp[2]*2+tmp[0]*tmp[0]; } void divide(int u){ ans+=calc(u,0); vis[u]=1; for(int i=head[u];~i;i=edges[i].nex){ int v = edges[i].v; if(vis[v])continue; ans-=calc(v,edges[i].w); maxp[rt=0]=sum=siz[v]; getrt(v,0); getrt(rt,0); divide(rt); } } int main(){ memset(head,-1,sizeof(head)); int n; scanf("%d",&n); for(int i=1;i<n;i++){ int u,v,w; scanf("%d %d %d",&u,&v,&w); w%=3; add(u,v,w); add(v,u,w); } maxp[0]=sum=n; getrt(1,0); getrt(rt,0); divide(rt); int gg = gcd(ans,n*n); printf("%d/%d",ans/gg,(n*n)/gg); }
|