• 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
  • 相关阅读:
    hdu 2553 N皇后问题(dfs)
    hdu 1043 Eight(双向bfs)
    牛人的ACM经验 (转)
    康托和逆康托展开(转)
    hiho Mission Impossible 6(模拟 未提交验证。。)
    数组越界也可以这么巧~~~
    poj 1679 The Unique MST(次小生成树)
    zoj 3204 Connect them(最小生成树)
    hdu 4463 Outlets(最小生成树)
    廖雪峰Java1-2程序基础-8字符和字符串
  • 原文地址:https://www.cnblogs.com/gryzy/p/6179672.html
Copyright © 2020-2023  润新知