luogu2634

P2634 [National Team] Cong Cong cocoa

Title Description

Cong Cong and Cocoa brothers, two of them often fight for some chores, such as home only last a Popsicle and they both want to eat, two people want to play computer (but they only have one computer at home) ... ... encounter this problem, in general, like the stone scissors cloth, but they are already tired of playing this game a low IQ.

Their father soon to be sick of their bickering, so he invented a new game: painting of n "points" on paper by the father, and this n-th "point" just communicating with the n-1 "edge" ( In fact, this is a tree). And has a number on each "edge." Followed by the Cong Cong and cocoa were then selected a point (of course, the choice of site when they can not see the tree), if all the numbers add up to the edge between two points and happens to be a multiple of 3, the penalty Cong Cong wins, otherwise the cocoa win.

Cong Cong loves to think, after each game will carefully study the tree, I would like to know the probability of winning for yourself how much this picture. Now you help find this value to verify Cong Cong answer is correct.

Input Format

The first input line comprises a positive integer n. N-1 rear lines of three integers x, y, W, x represents a number between there is an edge point and the point number y, the above number is w.

Output Format

The output probabilities (i.e. "a / b" form, where a and b must be prime to a probability of 1, the output "1/1"), i.e. at about fraction.

Sample input and output

Input # 1
5
1 2 1
1 3 2
1 4 1
2 5 3
Output # 1
13/25

Description / Tips

[Sample Description]

13 are set to point (1,1) (2,2) (2,3) (2,5) (3,2) (3,3) (3,4) (3,5) (4,3 ) (4,4) (5,2) (5,3) (5,5).

[Data] scale

To 100% of the data, n <= 20000.

 

sol: dp tree can also be dotted (written long time ago (fog, dp [i] [J] i is expressed in the subtree rooted at the number i% i = j, and the

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0; bool f=0; char ch=' ';
    while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
    while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0) {putchar('-'); x=-x;}
    if(x<10) {putchar(x+'0'); return;}
    write(x/10); putchar((x%10)+'0');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=20005,M=40005;
int n,dp[N][3],ans=0;
int tot=0,Next[M],to[M],val[M],head[N];
inline void Link(int x,int y,int z){Next[++tot]=head[x]; to[tot]=y; val[tot]=z; head[x]=tot;}
inline void dfs(int x,int fat)
{
    int e,i,j;
    dp[x][0]=1; dp[x][1]=dp[x][2]=0;
    for(e=head[x];e;e=Next[e]) if(to[e]!=fat)
    {
        dfs(to[e],x);
        for(i=0;i<3;i++)
        {
            ans+=dp[x][i]*dp[to[e]][(6-i-val[e])%3]*2;
        }
        for(i=0;i<3;i++)
        {
            dp[x][(i+val[e])%3]+=dp[to[e]][i];
        }
    }
//    cout<<x<<' '<<dp[x][0]<<' '<<dp[x][1]<<' '<<dp[x][2]<<endl;
}
int main()
{
    int i,x,y,z;
    R(n);
    for(i=1;i<n;i++)
    {
        R(x); R(y); z=read()%3; Link(x,y,z); Link(y,x,z);
    }
    dfs(1,0);
    ans+=n;
    int gg=__gcd(n*n,ans);
    write(ans/gg); putchar('/'); Wl(n*n/gg);
    return 0;
}
/*
input
5
1 2 1
1 3 2
1 4 1
2 5 3
output
13/25
*/
View Code
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=20005,M=40005,inf=0x3f3f3f3f;
int n,re=0,tot=0,Next[M],to[M],val[M],head[M],rt,sum,sz[N],pp[N],arr[N],tong[3],gg;
inline void add(int x,int y,int z){Next[++tot]=head[x];to[tot]=y;val[tot]=z;head[x]=tot;}
inline int gcd(int x,int y){return (y==0)?x:gcd(y,x%y);}
inline void getrt(int x,int fa)
{
    int i; sz[x]=1; pp[x]=0;
    for(i=head[x];i;i=Next[i])
    {
        if(!arr[to[i]]&&to[i]!=fa){getrt(to[i],x); sz[x]+=sz[to[i]]; pp[x]=max(pp[x],sz[to[i]]);}
    }pp[x]=max(pp[x],sum-pp[x]); if(pp[x]<pp[rt])rt=x;
}
inline void dfs(int x,int fa,int pre)
{
    tong[pre]++; int i;
    for(i=head[x];i;i=Next[i])
    {
        if(to[i]!=fa&&!arr[to[i]])dfs(to[i],x,(pre+val[i])%3);
    }
}
inline void calc(int x,int op,int v)
{
    tong[0]=tong[1]=tong[2]=0; dfs(x,0,v%3); re+=op*(2*tong[1]*tong[2]+tong[0]*tong[0]+tong[1]+tong[2]);
}
inline void solve(int x)
{
    int i; arr[x]=1; calc(x,1,0);
    for(i=head[x];i;i=Next[i])
    {
        if(!arr[to[i]])
        {
            calc(to[i],-1,val[i]); sum=sz[to[i]]; pp[rt=0]=inf; getrt(to[i],0); solve(rt);
        }
    }
}
int main()
{
    int i,x,y,z; scanf("%d",&n); sum=pp[rt=0]=n;
    for(i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z);
    }getrt(1,0); solve(rt); gg=gcd(re,n*n); printf("%d/%d\n",re/gg,n*n/gg);
}
Point worth

 

Guess you like

Origin www.cnblogs.com/gaojunonly1/p/11230656.html