The meaning of problems Portal
Ideas: The basic idea of the partition point, NUM array record path length from the start point u are the path length of 1, 2 or 3 (the 3 modulo sense), then do a simple enough repellent capacity.
To avoid the trouble of counting, <u, u> such points is calculated separately, which is the final answer plus n it.
bzoj not supported c14, my code is in Los Valley post.
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;++i) #define dep(i,b,a) for(int i=b;i>=a;--i) #define clr(a,b) memset(a,b,sizeof(a)) #define pb push_back #define pii pair<int,int > using namespace std; typedef long long ll; ll rd() { ll x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int maxn=20010; const int inf=0x3f3f3f3f; int T,n,m; struct edge{ int to,w; }; vector<edge >ve[maxn]; ll ans=0; int rt,mx,dis[maxn]; ll num[3]; int siz[maxn],size; bool vis[maxn]; int u,v,w; void getrt(int u,int p){ siz[u]=1; int tmp=0; for(auto &st:ve[u]){ int v=st.to; if(vis[v]||v==p)continue; getrt(v,u); siz[u]+=siz[v]; tmp=max(tmp,siz[v]); } tmp=max(size-siz[u],tmp); if(tmp<mx){ mx=tmp; rt=u; } } void getdis(int u,int p){ dis[u]%=3; num[dis[u]]++; for(auto &st:ve[u]){ int v=st.to,w=st.w; if(v==p||vis[v])continue; dis[v]=(dis[u]+w)%3; getdis(v,u); } } 'Ll cal ( ;int w, int val) { push [u] = val; CLR (num, 0 ); getdis (n, 0 ); I'll = 2 * num [ 1 ] or [ 2 ] + 2 * (num [ 0 ] - 1 ) + (num [ 0 ] - 1 ) * (num [ 0 ] - 1 - 1 ); return sum; } Void DFS ( int n) { force [u] = 1 ans + cal (n, 0); for(auto &st:ve[u]){ int v=st.to,w=st.w; if(vis[v])continue; ans-=cal(v,w); size=siz[v]; mx=inf; getrt(v,0); dfs(rt); } } int main(){ cin>>n; rep(i,1,n-1){ u=rd(),v=rd(),w=rd(); w=w%3; ve[u].pb({v,w}); ve[v].pb({u,w}); } size=n; mx=inf; getrt(1,0); dfs(1); ans+=n; ll an2=1ll*n*n; ll gc=__gcd(an2,ans); printf("%lld/%lld\n",ans/gc,an2/gc); }