bzoj 2152聪聪可可

2152: 聪聪可可

Time Limit: 3 Sec  Memory Limit: 259 MB

Description

聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃、两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好了,可是他们已经玩儿腻了这种低智商的游戏。他们的爸爸快被他们的争吵烦死了,所以他发明了一个新游戏:由爸爸在纸上画n个“点”,并用n-1条“边”把这n个“点”恰好连通(其实这就是一棵树)。并且每条“边”上都有一个数。接下来由聪聪和可可分别随即选一个点(当然他们选点时是看不到这棵树的),如果两个点之间所有边上数的和加起来恰好是3的倍数,则判聪聪赢,否则可可赢。聪聪非常爱思考问题,在每次游戏后都会仔细研究这棵树,希望知道对于这张图自己的获胜概率是多少。现请你帮忙求出这个值以验证聪聪的答案是否正确。

Input

输入的第1行包含1个正整数n。后面n-1行,每行3个整数x、y、w,表示x号点和y号点之间有一条边,上面的数是w。

Output

以即约分数形式输出这个概率(即“a/b”的形式,其中a和b必须互质。如果概率为1,输出“1/1”)。

Sample Input

5
1 2 1
1 3 2
1 4 1
2 5 3

Sample Output

13/25
【样例说明】
13组点对分别是(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)。

【数据规模】
对于100%的数据,
n<=20000。

——————————————————————————————————————————————

这道题是点分治的第三道了,和上两题基本一样,只不过把求距离小于k改为了是3的倍数。

很快就打完了,可是还是出了错误。注意看样例,(a,b)、(b,a)是两个对。还犯了一个该撞墙的错误,只记的计算对数了,忘记了输出比例了,还在那里调呢!就为这个错误提交了三次,还琢磨呢,该对了……我鄙视自己。

——————————————————————————————————————————————

  1 //bzoj 2152聪聪与可可
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6  
  7 using namespace std;
  8 const long long maxn=20010;
  9 long long n;
 10 long long ans=0;
 11 long long mi,root,jst;
 12 struct edge
 13 {
 14     long long u,v,w,next;
 15 }e[maxn*2];
 16 long long head[maxn],js;
 17 long long siz[maxn],dis[maxn],mx[maxn];
 18 bool vis[maxn];
 19 void readint(long long &x)
 20 {
 21     char c=getchar();
 22     long long f=1;
 23     for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-f;
 24     x=0;
 25     for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
 26     x*=f;
 27 }
 28 void addage(long long u,long long v,long long w)
 29 {
 30     e[++js].u=u;e[js].v=v;e[js].w=w;
 31     e[js].next=head[u];head[u]=js;
 32 }
 33 void dfssize(long long u,long long f)
 34 {
 35     siz[u]=1;mx[u]=0;
 36     for(long long i=head[u];i;i=e[i].next)
 37     {
 38         long long v=e[i].v;
 39         if(v!=f && !vis[v])
 40         {
 41             dfssize(v,u);
 42             siz[u]+=siz[v];
 43             if(siz[v]>mx[u])mx[u]=siz[v];
 44         }
 45     }
 46 }
 47 void dfsroot(long long r,long long u,long long f)
 48 {
 49     if(siz[r]-siz[u]>mx[u])mx[u]=siz[r]-siz[u];
 50     if(mi>mx[u])
 51     {
 52         mi=mx[u];
 53         root=u;
 54     }
 55     for(long long i=head[u];i;i=e[i].next)
 56     {
 57         long long v=e[i].v;
 58         if(v!=f && !vis[v])
 59         {
 60             dfsroot(r,v,u);
 61         }
 62     }
 63 }
 64 void dfsdis(long long u,long long d,long long f)
 65 {
 66     dis[jst++]=d%3;
 67     for(long long i=head[u];i;i=e[i].next )
 68     {
 69         long long v=e[i].v;
 70         if(v!=f && !vis[v])
 71         {
 72             dfsdis(v,d+e[i].w,u);
 73         }
 74     }
 75 }
 76 long long calc(long long u,long long d)
 77 {
 78     long long dds=0;
 79     jst=0;
 80     dfsdis(u,d,0);
 81     long long js0=0,js1=0,js2=0;
 82     for(long long i=0;i<jst;i++)
 83     {
 84         if(dis[i]==0)js0++;
 85         else if(dis[i]==1)js1++;
 86         else js2++;
 87     }
 88     return js0*js0+js1*js2*2;
 89 }
 90 void dfs(long long u)
 91 {
 92     mi=n;
 93     dfssize(u,0);
 94     dfsroot(u,u,0);
 95 //  cout<<"+"<<root<<","<<calc(root,0)<<endl;
 96     ans+=calc(root,0);
 97     vis[root]=1;
 98     for(long long i=head[root];i;i=e[i].next)
 99     {
100         long long v=e[i].v;
101         if(!vis[v])
102         {
103 //          cout<<"-"<<v<<","<<calc(v,e[i].w)<<endl;
104             ans-=calc(v,e[i].w);
105             dfs(v);
106         }
107     }
108 }
109 long long gcd(long long a,long long b)
110 {
111     if(a%b==0)return b;
112     else return gcd(b,a%b);
113 }
114 int main()
115 {
116     readint(n);
117     for(long long u,v,w,i=1;i<n;i++)
118     {
119         readint(u);readint(v);readint(w);
120         w=w%3;
121         addage(u,v,w);addage(v,u,w);
122     }
123     dfs(1);
124     long long tp=gcd(ans,n*n);
125     cout<<ans/tp<<"/"<<n*n/tp<<endl;
126     return 0;
127 }
View Code

 

posted on 2016-12-14 15:55  gryzy  阅读(183)  评论(0编辑  收藏  举报

导航