[National Training Team] Congcong Cocoa

Keywords: PHP

Title Description

Congcong and Coco brothers often fight over trivial matters, such as the last ice stick left at home and both want to eat, and both want to play with computers (but they only have one computer)... When faced with this problem, stone scissors are usually good, but they are tired of playing such low IQ games.

Their father was tired of their quarrel, so he invented a new game: his father drew n "points" on paper and connected them with n-1 "edges" (in fact, this is a tree). And there is a number on each edge. Next, Congcong and Cocoa choose one point (of course, they can't see the tree when choosing the point). If the sum of all the edges between the two points is exactly a multiple of three, Congcong wins, otherwise it can win.

Congcong is very fond of thinking. After every game, he will study the tree carefully, hoping to know what his winning probability is for this picture. Now, please help me to find out the value to verify whether Congcong's answer is correct.

Input format

The first line of input contains a positive integer n. The next n-1 line, each line with three integers x, y, w, indicates that there is an edge between the point X and the point y, and the number above is w.

Output format

Output this probability in the form of approximate fractions (i.e. in the form of "a/b", where a and B must be mutually prime. If the probability is 1, output "1/1".

Input
5
1 2 1
1 3 2
1 4 1
2 5 3
putout
13/25
Naked Point Dividing and Curing
 
3 Numbers of Path% from Record Point to Divide and Conquer Point
According to common sense
ans+=cnt[0]*cnt[0]+cnt[1]*cnt[2]+cnt[2]*cnt[1];
 
 
But we can find that there are still the following situations
Although b and c are in the same subtree, we think of them as two subtree paths.
So let's say that when we visit the subtree later, we use the solution function to count out the wrong answers and subtract them.
 
This is an example!!!
#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=20005;
using namespace std;
template<typename T>inline void rd(T&x)
{
	char c;bool f=0;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
	x=c^48;
	while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
	if(f)x=-x; 
} 
int n,m,rt,k,SIZE,hd[maxn],ANS;
int f[maxn],dis[maxn],use[maxn],cnt[10],size[maxn];

struct node
{
	int to,nt,val;
}e[maxn<<1];

inline void add(int x,int y,int z)
{
	e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].val=z;
	e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].val=z;
}

inline void Get_rt(int x,int fa)
{
	size[x]=1;f[x]=0;
	for(int i=hd[x];i;i=e[i].nt)
	{
		int v=e[i].to;
		if(use[v]||v==fa)continue;
		Get_rt(v,x);
		f[x]=max(f[x],size[v]);
		size[x]+=size[v];
	}
	f[x]=max(f[x],SIZE-size[x]);
	if(f[rt]>f[x])rt=x;
} 



inline void Get_dis(int x,int fa)
{
	++cnt[dis[x]];
 	for(int i=hd[x];i;i=e[i].nt)
 	{
 		int v=e[i].to;
 		if(use[v]||v==fa)continue;
 		dis[v]=(dis[x]+e[i].val)%3;
 		Get_dis(v,x);
	}
} 
inline int  Get_num(int x,int D)
{
	cnt[1]=cnt[2]=cnt[0]=0;
	dis[x]=D%3;
	Get_dis(x,0);	
	re cnt[0]*cnt[0]+cnt[1]*cnt[2]+cnt[2]*cnt[1];
}


inline void dfs(int x)
{
	use[x]=1;ANS+=Get_num(x,0);
	for(int i=hd[x];i;i=e[i].nt)
	{
		int v=e[i].to;
		if(use[v])continue;
		ANS-=Get_num(v,e[i].val);
		//Excuse me, subtract all invalid states 
		f[rt=0]=n;SIZE=size[v];
		Get_rt(v,0);
		dfs(rt);	
	}
}

inline int gcd(int a,int b){re b?gcd(b,a%b):a;} 

int main()
{
	freopen("in.txt","r",stdin);
	rd(n);
	int x,y,z;
	inc(i,2,n)
	{
		rd(x),rd(y),rd(z);
		add(x,y,z);
	}
	
	f[rt]=SIZE=n;
	Get_rt(1,0);
	
	dfs(rt);
	
	int d=gcd(ANS,n*n);
	printf("%d/%d",ANS/d,n*n/d);
	
	re 0;
}

  

 
 
 

Posted by danf_1979 on Fri, 11 Oct 2019 12:51:03 -0700