【BZOJ 2152】 聪聪可可

为了做那个列表 扯到这么远........
不能乱立Flag啊!!!

#include <cstdio>
#include <iostream>
#define MAXN 400000
using namespace std;
int num[MAXN],g[MAXN],nnext[MAXN],cost[MAXN],tot;
int n,root,size[MAXN],f[MAXN],sum;
int ans=0;
bool b[MAXN];
void Find_Root(int x,int fa)
{
	f[x]=0;
	size[x]=1;
	for(int i=g[x];i;i=nnext[i])
	if(num[i]!=fa&&!b[num[i]])
	{
		Find_Root(num[i],x);
		f[x]=max(f[x],size[num[i]]);
		size[x]+=size[num[i]];
	}
	f[x]=max(f[x],sum-f[x]);
	if(f[x]<f[root]) root=x;
}	
int T[3];
void Dfs(int x,int fa,int k)
{
	T[k]++;
	for(int i=g[x];i;i=nnext[i])
	if(num[i]!=fa&&!b[num[i]])
		Dfs(num[i],x,(k+cost[i])%3);
}
void Do(int x)
{
	b[x]=true;
	int N0=0,N1=0,N2=0;
	for(int i=g[x];i;i=nnext[i])
	if(!b[num[i]])
	{
		T[0]=T[1]=T[2]=0;
		Dfs(num[i],-1,cost[i]);
		ans+=T[0]+T[0]*N0+T[1]*N2+T[2]*N1;
		N0+=T[0],N1+=T[1],N2+=T[2];
		sum=size[num[i]];
		root=0;
		Find_Root(num[i],-1);
		Do(root);
	}
//	cout<<x<<' '<<N0<<' '<<N1<<' '<<N2<<endl;
}
int Gcd(int x,int y)
{
	if(y==0) return x;
	return Gcd(y,x%y);
}
int main()
{
	cin>>n; if(n==0) {cout<<"0/1";return 0;}
	for(int i=1;i<n;i++)
	{
		int x,y,z;
		scanf("%d %d %d",&x,&y,&z);
		tot++;nnext[tot]=g[x];g[x]=tot;num[tot]=y;cost[tot]=z%3;
		tot++;nnext[tot]=g[y];g[y]=tot;num[tot]=x;cost[tot]=z%3;
	}
	root=0;
	f[0]=n+1;
	sum=n;
	Find_Root(1,-1);
	Do(root);
	
	ans=ans*2+n;
	n=n*n;
	int t=Gcd(ans,n);
	cout<<ans/t<<'/'<<n/t;
	return 0;
} 
posted @ 2016-01-18 16:17  sxb_201  阅读(146)  评论(0编辑  收藏  举报