• bzoj 2152: 聪聪可可


     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int N=20010;
     5 int t[5],head[N],son[N],f[N],d[N],root,ans,n,sum,cnt;
     6 bool vis[N];
     7 struct ee{int to,next,v;}e[N*2];
     8 void insert(int u,int v,int w){
     9     e[++cnt].to=v;e[cnt].next=head[u];e[cnt].v=w;head[u]=cnt;
    10 }
    11  
    12 int gcd(int a1,int a2)
    13 {
    14     int a3=a1%a2;
    15     for(;a3;)
    16       {
    17         a1=a2;
    18         a2=a3;
    19         a3=a1%a2;
    20       }
    21     return a2;
    22 }
    23  
    24 void getroot(int x,int fa){
    25     son[x]=1;f[x]=0;
    26     for (int i=head[x];i;i=e[i].next){
    27         int v=e[i].to;
    28         if (!vis[v]&&v!=fa){
    29             getroot(v,x);
    30             son[x]+=son[v];
    31             f[x]=max(f[x],son[v]);
    32         }
    33     }
    34     f[x]=max(f[x],sum-son[x]);
    35     if (f[root]>f[x])root=x;
    36 }
    37  
    38 void getdeep(int x,int fa){
    39     t[d[x]]++;
    40     for (int i=head[x];i;i=e[i].next){
    41         int v=e[i].to;
    42         if (v!=fa&&!vis[v]){
    43             d[v]=(d[x]+e[i].v)%3;
    44             getdeep(v,x);
    45         }
    46     }
    47 }
    48  
    49 int cal(int x,int now){
    50     t[0]=t[1]=t[2]=0;
    51     d[x]=now;
    52     getdeep(x,0);
    53     return t[1]*t[2]*2+t[0]*t[0];
    54 }
    55  
    56 void work(int x){
    57     ans+=cal(x,0);
    58     vis[x]=1;
    59     for (int i=head[x];i;i=e[i].next){
    60         int v=e[i].to;
    61         if (!vis[v]) {
    62             ans-=cal(v,e[i].v);
    63             root=0;sum=son[v];
    64             getroot(v,0);
    65             work(root);
    66         }
    67     }
    68 }
    69  
    70 int main(){
    71     scanf("%d",&n);
    72     int u,v,w;
    73     for (int i=1;i<n;i++){
    74         scanf("%d%d%d",&u,&v,&w);
    75         w%=3;
    76         insert(u,v,w);
    77         insert(v,u,w);
    78     }
    79     f[0]=sum=n;
    80     root=0;
    81     getroot(1,0);
    82     work(root);
    83     int t=gcd(ans,n*n);
    84     printf("%d/%d",ans/t,n*n/t);
    85 }

    树的点分治  首先找树的重心,把根节点设为树的重心。然后进行点分治(就是从根开始,看经过根的方案数,在把根删掉,求每棵子树)。

  • 相关阅读:
    YYC松鼠视频pro版安装实操001
    YYC松鼠视频短信对接教程
    此处指讲解自定义的一些目录结构及组件-yyc松鼠短视频系统
    APP启动无视频数据-YYC松鼠短视频系统
    后台提示登录失败----YYC松鼠短视频开源
    C++静态成员变量和静态成员函数
    内联函数和宏定义的区别
    C++中的接口继承和实现继承
    拷贝构造函数(define)
    类的封装
  • 原文地址:https://www.cnblogs.com/xydddd/p/5299068.html
Copyright © 2020-2023  润新知