树形dp。
本来是想做一系列树分治的,结果这道题树形dp就可以了(膜popoqqq大神)
f数组保存每个节点距离为0,1,2的点对数量。
不断统计就可以辣。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 20000 + 10; const int maxm = 40000 + 10; struct data { int a,b,c; void rotate() { swap(a,b); swap(a,c); } data operator += (const data rhs) { a+=rhs.a; b+=rhs.b; c+=rhs.c; } data() {a=1;b=0;c=0;} }f[maxn]; int n,res; int g[maxn],v[maxm],next[maxm],c[maxm],eid; void addedge(int a,int b,int C) { v[eid]=b; c[eid]=C; next[eid]=g[a]; g[a]=eid++; v[eid]=a; c[eid]=C; next[eid]=g[b]; g[b]=eid++; } void update(data x,data y) { res+=x.a*y.a; res+=x.b*y.c; res+=x.c*y.b; } void dfs(int u,int from) { for(int i=g[u];~i;i=next[i]) if(v[i]!=from) { dfs(v[i],u); for(int j=c[i];j;j--) f[v[i]].rotate(); update(f[u],f[v[i]]); f[u]+=f[v[i]]; } } int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } int main() { memset(g,-1,sizeof(g)); scanf("%d",&n); for(int i=1,u,v,w;i<n;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w%3); } dfs(1,0); res=res*2+n; int d=gcd(res,n*n); printf("%d/%d\n",res/d,n*n/d); return 0; }
时间: 2024-10-24 14:34:30