zoukankan      html  css  js  c++  java
  • bzoj2152

    题解:

      随便点分治,用一个t数组,t[i]代表有u到root的值mod3==i; 那么答案就是:t[0]*t[0]+t[1]*t[2]*2;

    代码:

      

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define N 20005
    using namespace std;
    int pre[N*2],now[N],v[N*2],val[N*2];
    int d[N],son[N],f[N];
    int t[4];
    bool vis[N];
    int tot,all,n,ans,root;
    int read()
    {
        int x=0; char ch; bool bo=0;
        while (ch=getchar(), ch<'0'||ch>'9') if (ch=='-') bo=1;
        while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9');
        if (bo) return -x; return x; 
    }
    void ins(int a,int b,int c)
    {
        ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c;
    }
    int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    void getroot(int u,int fa)
    {
        son[u]=1; f[u]=0;
        for (int p=now[u]; p; p=pre[p])
        {
            int vv=v[p];
            if (vv==fa || vis[vv]) continue;
            getroot(vv,u); son[u]+=son[vv];
            f[u]=max(f[u],son[vv]);
        }
        f[u]=max(f[u],all-son[u]);
        if (f[u]<f[root]) root=u;
    }
    void getarray(int u,int fa)
    {
        t[d[u]]++;
        for (int p=now[u]; p; p=pre[p])
        {
            int vv=v[p];
            if (vv==fa||vis[vv]) continue;
            d[vv]=(d[u]+val[p])%3;
            getarray(vv,u);
        }
    }
    int calc(int u,int value)
    {
        t[0]=t[1]=t[2]=0; d[u]=value;
        getarray(u,0);
        return t[0]*t[0]+t[1]*t[2]*2;
    }
    void solve(int u)
    {
        ans+=calc(u,0); vis[u]=1;
        for (int p=now[u]; p; p=pre[p])
        {
            int vv=v[p];
            if (vis[vv]) continue;
            ans-=calc(vv,val[p]);
            root=0; all=son[vv];
            getroot(vv,0);
            solve(root);
        }
    }
    int main()
    {
        n=read();
        for (int i=1; i<n; i++)
        {
            int a=read(),b=read(),val=read()%3;
            ins(a,b,val); ins(b,a,val);
        }
        ans=0;
        f[root=0]=all=n; getroot(1,0); 
        solve(root);
        int kk=gcd(ans,n*n);
        printf("%d/%d
    ",ans/kk,n*n/kk);
    }
    View Code
  • 相关阅读:
    Mysql与Sql Server查询数据库中表以及表字段
    linux系统常用命令
    linux tomcat安装以及配置
    mysql 5.7 设置root远程访问
    linux jdk安装
    ubuntu系统阅读CHM文档的最终解决方案
    ubuntu18.04完全卸载mysql的命令
    linux下使用cd命令进入wine容器中的windows路径
    Python中yield关键字的用法及运行逻辑
    Ubuntu18..04.2服务器版设置redis开机启动遇到的问题
  • 原文地址:https://www.cnblogs.com/HQHQ/p/5469102.html
Copyright © 2011-2022 走看看