要求出两点间距离==0(mod3) 的数量,然后除以(n*n)
设f[i][j]为i的子树到i的距离==j(mod3)的数量,然后做树形dp即可
因为要最简,所以要求一下gcd,然后除下去
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int maxn=20020; 6 7 int rd(){ 8 int x=0;char c=getchar(); 9 while(c<'0'||c>'9') c=getchar(); 10 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 11 return x; 12 } 13 14 15 struct Edge{ 16 int b,l,ne; 17 }eg[maxn*2],son[maxn]; 18 int N; 19 int f[maxn][3],f2[maxn][3],egh[maxn],sonh[maxn],ect,sct; 20 int ansp; 21 22 inline void adeg(int a,int b,int c){ 23 eg[ect].b=b;eg[ect].l=c;eg[ect].ne=egh[a];egh[a]=ect++; 24 } 25 26 void build(int x,int fa){ 27 for(int i=egh[x];i!=-1;i=eg[i].ne){ 28 int b=eg[i].b;if(b==fa) continue; 29 son[sct].b=b;son[sct].l=eg[i].l;son[sct].ne=sonh[x];sonh[x]=sct++; 30 build(b,x); 31 } 32 } 33 34 void dfs(int x){ 35 f[x][0]=1; 36 for(int i=sonh[x];i!=-1;i=son[i].ne) dfs(son[i].b); 37 for(int i=sonh[x];i!=-1;i=son[i].ne){ 38 int b=son[i].b,l=son[i].l; 39 for(int j=0;j<=2;j++) f[x][(j+l)%3]+=f[b][j],f2[b][(j+l)%3]=f[b][j]; 40 }ansp+=f[x][0]; 41 for(int i=sonh[x];i!=-1;i=son[i].ne){ 42 int b=son[i].b,l=son[i].l; 43 for(int j=0;j<=2;j++) ansp+=f2[b][(3-j%3)%3]*(f[x][j]-f2[b][j]); 44 } 45 } 46 47 int gcd(int a,int b){ 48 if(!b) return a; 49 else return gcd(b,a%b); 50 } 51 52 int main(){ 53 int i,j,k; 54 N=rd(); 55 memset(egh,-1,sizeof(egh));memset(sonh,-1,sizeof(sonh)); 56 for(i=1;i<N;i++){ 57 int a=rd(),b=rd(),c=rd(); 58 adeg(a,b,c);adeg(b,a,c); 59 }build(1,0);dfs(1); 60 i=gcd(ansp,N*N); 61 printf("%d/%d\n",ansp/i,N*N/i); 62 }