[bzoj2152]聪聪可可

树分治。

边的话存的时候存成mod 3后的边就行,然后其他的就是套模板了。(数组开太大会被T的。。。)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cmath>
 7 using namespace std;
 8 
 9 const int N=50000;
10 int h[20010],r[40010],to[40010],w[40010],d[20010],sz[20010],f[20010],root,sum,tot,n,ans,t[5];
11 bool v[20010];
12 int gcd(int a,int b){return b?gcd(b,a%b):a;}
13 void ins(int u,int v,int z){
14     to[tot]=v;
15     w[tot]=z%3;
16     r[tot]=h[u];
17     h[u]=tot++;
18 }
19 void getRoot(int x,int fa){
20     sz[x]=1;f[x]=0;
21     for(int i=h[x];i!=-1;i=r[i]){
22         if(!v[to[i]]&&to[i]!=fa){
23             getRoot(to[i],x);
24             sz[x]+=sz[to[i]];
25             f[x]=max(f[x],sz[to[i]]);
26         }
27     }
28     f[x]=max(f[x],sum-sz[x]);
29     if(f[x]<f[root])root=x;
30 }
31 void getDeep(int x,int fa){
32     t[d[x]]++;
33     for(int i=h[x];i!=-1;i=r[i]){
34         if(!v[to[i]]&&to[i]!=fa){
35             d[to[i]]=(d[x]+w[i])%3;
36             getDeep(to[i],x);
37         }
38     }
39 }
40 int calc(int x,int val){
41     d[x]=val;t[0]=t[1]=t[2]=0;
42     getDeep(x,0);
43     return t[0]*t[0]+t[1]*t[2]*2;
44 }
45 void work(int x){
46     ans+=calc(x,0);
47     v[x]=1;
48     for(int i=h[x];i!=-1;i=r[i]){
49         if(!v[to[i]]){
50             ans-=calc(to[i],w[i]);
51             root=0;
52             sum=sz[to[i]];
53             getRoot(to[i],0);
54             work(root);
55         }
56     }
57 }
58 inline int read(){
59     static int f,ret;
60     static char c;
61     ret=0;f=1;
62     c=getchar();
63     while(c>'9'||c<'0'){
64         if(c=='-')f=-1;
65         c=getchar();
66     }
67     while(c>='0'&&c<='9')ret=(ret<<1)+(ret<<3)+c-'0',c=getchar();
68     return ret*f;
69 }
70 int main(){
71     n=read();
72     memset(h,-1,sizeof(h));
73     for(int i=1,u,v,z;i<n;i++){
74         u=read();
75         v=read();
76         z=read();
77         ins(u,v,z);ins(v,u,z);
78     }
79     f[0]=sum=n;
80     getRoot(1,0);
81     work(root);
82     int g=gcd(ans,n*n);
83     printf("%d/%d\n",ans/g,n*n/g);
84 }
View Code

 

posted @ 2017-01-25 15:17  KingSann  阅读(108)  评论(0编辑  收藏  举报