bzoj2152 聪聪可可

题目链接

本人写的第一道点分治嘿嘿嘿

点分治重要的就是要找重心和标记已计算过的点、减掉重复计算的部分

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int n;
 34 int head[20020],next[40040],zhi[40040],ed,si[20020],w[20020],v[40040];
 35 int root,sum,ans,bo[20020];
 36 void add(int a,int b,int c)
 37 {
 38     next[++ed]=head[a],head[a]=ed,zhi[ed]=b,v[ed]=c;
 39     next[++ed]=head[b],head[b]=ed,zhi[ed]=a,v[ed]=c;
 40 }
 41 int gcd(int a,int b)
 42 {
 43     int c;
 44     while(a%b)c=a%b,a=b,b=c;
 45     return b;
 46 }
 47 void getroot(int x,int fa)
 48 {
 49     si[x]=1;w[x]=0;
 50     for(int i=head[x];i;i=next[i])if(!bo[zhi[i]]&&zhi[i]!=fa)
 51     {
 52         getroot(zhi[i],x);
 53         si[x]+=si[zhi[i]];
 54         w[x]=max(w[x],si[zhi[i]]);
 55     }
 56     w[x]=max(w[x],sum-si[x]);
 57     if(w[x]<w[root])root=x;
 58 }
 59 int dis[20020],shu[3];
 60 void getans(int x,int fa)
 61 {
 62     shu[dis[x]]++;
 63     for(int i=head[x];i;i=next[i])
 64         if(zhi[i]!=fa&&!bo[zhi[i]])
 65         {
 66             dis[zhi[i]]=(dis[x]+v[i])%3;
 67             getans(zhi[i],x);
 68         }
 69 }
 70 int js(int x,int temp)
 71 {
 72     shu[0]=shu[1]=shu[2]=0;
 73     dis[x]=temp;getans(x,0);
 74     return shu[1]*shu[2]*2+shu[0]*shu[0];
 75 }
 76 void solve(int x)
 77 {
 78     ans+=js(x,0);
 79     bo[x]=1;
 80     for(int i=head[x];i;i=next[i])if(!bo[zhi[i]])
 81     {
 82         ans-=js(zhi[i],v[i]);
 83         root=0;sum=si[zhi[i]];
 84         getroot(zhi[i],0);
 85         solve(root);
 86     }
 87 }
 88 int CSC()
 89 {
 90     inin(n);
 91     re(i,2,n)
 92     {
 93         int q,w,e;
 94         inin(q),inin(w),inin(e);
 95         add(q,w,e%3);
 96     }
 97     sum=w[0]=n;
 98     getroot(1,0);
 99     solve(root);
100     int wocao=gcd(ans,n*n);
101     printf("%d/%d",ans/wocao,n*n/wocao);
102     return 0;
103 }

 

posted @ 2016-02-16 16:05  HugeGun  阅读(347)  评论(1编辑  收藏  举报