[bzoj2152]聪聪可可

poj1741一样,只是将统计每一个点的深度改为深度除以3余数为012的点数量,注意(1,2)(2,1)算两种。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define N 20005
 6 struct ji{
 7     int nex,to,len;
 8 }edge[N<<1];
 9 int E,r,n,x,y,z,ans,a[11],head[N],vis[N],sz[N];
10 int gcd(int x,int y){
11     if (!y)return x;
12     return gcd(y,x%y);
13 }
14 void add(int x,int y,int z){
15     edge[E].nex=head[x];
16     edge[E].to=y;
17     edge[E].len=z;
18     head[x]=E++;
19 }
20 void tot(int k,int fa,int sh){
21     a[sh]++;
22     for(int i=head[k];i!=-1;i=edge[i].nex)
23         if ((!vis[edge[i].to])&&(edge[i].to!=fa))
24             tot(edge[i].to,k,(sh+edge[i].len)%3);
25 }
26 int calc(int k,int p){
27     memset(a,0,sizeof(a));
28     tot(k,0,p);
29     return a[0]*a[0]+2*a[1]*a[2];
30 }
31 void get(int k,int fa){
32     int ma=0;
33     sz[k]=1;
34     for(int i=head[k];i!=-1;i=edge[i].nex)
35         if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
36             get(edge[i].to,k);
37             sz[k]+=sz[edge[i].to];
38             ma=max(ma,sz[edge[i].to]);
39         }
40     ma=max(ma,sz[0]-sz[k]);
41     if (ma<=sz[0]/2)r=k;
42 }
43 void dfs(int k){
44     ans+=calc(k,0);
45     vis[k]=1;
46     get(k,0);
47     for(int i=head[k];i!=-1;i=edge[i].nex)
48         if (!vis[edge[i].to]){
49             ans-=calc(edge[i].to,edge[i].len);
50             sz[0]=sz[edge[i].to];
51             get(edge[i].to,0);
52             dfs(r);
53         }
54 }
55 int main(){
56     scanf("%d",&n);
57     memset(head,-1,sizeof(head));
58     for(int i=1;i<n;i++){
59         scanf("%d%d%d",&x,&y,&z);
60         add(x,y,z%3);
61         add(y,x,z%3);
62     }
63     sz[0]=n;
64     get(1,0);
65     dfs(r);
66     x=gcd(n*n,ans);
67     printf("%d/%d",ans/x,n*n/x);
68 }
View Code

 

posted @ 2019-07-28 10:41  PYWBKTDA  阅读(119)  评论(0编辑  收藏  举报