Luo Gu P2634 [National Team] Cong Cong cocoa (dotted rule)

Portal
is doing a dotted governance practice your hand.
Mainly seek length tree \ (3 \) the number of multiple paths, of course, more convenient dotted rule
record path length \ (\% 3 \) number after the number, and you can find the current path, and by which make up \ (3 \) path of how many multiples
because it is a partial order, so the answer to \ (\ Times 2 \) , plus of course \ (i-> i \) of the total program \ (n- \) bar.

#include <bits/stdc++.h>
using namespace std;
const int MAXN=2e4+10;
int n;
int head[MAXN],to[MAXN*2],nxt[MAXN*2],val[MAXN*2],tot;
int siz[MAXN],maxp[MAXN],sum,rt,dead[MAXN];
int path[4],cnt,dis[MAXN],ans;

void add(int u,int v,int w){
    to[++tot]=v;nxt[tot]=head[u];val[tot]=w;head[u]=tot;
}

void getrt(int u,int fa){
    siz[u]=1;maxp[u]=0;
    for(int i=head[u];i;i=nxt[i]){
        if(to[i]==fa||dead[to[i]]) continue;
        getrt(to[i],u);
        siz[u]+=siz[to[i]];
        maxp[u]=max(maxp[u],siz[to[i]]);
    }
    maxp[u]=max(maxp[u],sum-siz[u]);
    if(maxp[u]<maxp[rt]) rt=u;
}

void getdis(int u,int fa,int w){
    dis[++cnt]=w;
    for(int i=head[u];i;i=nxt[i]){
        if(to[i]==fa||dead[to[i]]) continue;
        getdis(to[i],u,w+val[i]);
    }
}

void calc(int u){
    path[0]=1;
    for(int i=head[u];i;i=nxt[i]){
        if(dead[to[i]]) continue;
        cnt=0;
        getdis(to[i],u,val[i]);
        for(int j=1;j<=cnt;j++)
            if(dis[j]%3==0) ans+=path[0];
            else ans+=path[3-dis[j]%3];
        for(int j=1;j<=cnt;j++) path[dis[j]%3]++;
    }
    memset(path,0,sizeof(path));
}

void divide(int u){
    dead[u]=1;
    calc(u);
    for(int i=head[u];i;i=nxt[i]){
        if(dead[to[i]]) continue;
        maxp[rt=0]=sum=siz[to[i]];
        getrt(to[i],0);
        getrt(rt,0);
        divide(rt);
    }
}

int gcd(int a,int b){return b==0?a:gcd(b,a%b);}

int main(){
#ifndef ONLINE_JUDGE
    freopen("data.in","r",stdin);
    freopen("data.out","w",stdout);
#endif
    scanf("%d",&n);
    for(int i=1,u,v,w;i<n;i++){
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);add(v,u,w);
    }
    maxp[0]=sum=n;
    getrt(1,0);
    getrt(rt,0);
    divide(rt);
    ans=ans*2+n;
    int a=ans,b=n*n,d=gcd(a,b);
    printf("%d/%d\n",a/d,b/d);
    return 0;
}

Guess you like

Origin www.cnblogs.com/BakaCirno/p/12302574.html