"Surface"
To be an AK (CZYAK.C/.CPP/.PAS)
2s 128M
Czy is very hot. Because someone else said he was empty. In order to prove that he was not false, he decided to take AK in this match.
Now he is playing a game with others: in a tree randomly take two points, if the distance between the two points is a multiple of 4, then calculate Czy win, or the other side wins. Now Czy want to know the probability that he will win.
This probability is output in the form of a "A/b", where A and B must be coprime. If the probability is 1, output "1/1").
Multiple sets of data. For each set of data: The first row is a number n, indicating the number of nodes on the tree next N-1 A,b,c describes a to B has a path of length C when n=0 indicates read-in end
Number of data groups not exceeding 10
Input data
5
1 2 1
1 3 2
1 4 1
2 5 3
0
Output data
7/25
Data range
Data points |
Size of N |
Number of data groups |
Randomly generated data |
1 |
200 |
1 |
Is |
2 |
200 |
1 |
Is |
3 |
200 |
<=3 |
Is |
4 |
2000 |
<=3 |
Is |
5 |
2000 |
<=3 |
Is |
6 |
2000 |
<=5 |
Is |
7 |
20000 |
<=5 |
Whether |
8 |
20000 |
<=5 |
Whether |
9 |
20000 |
<=10 |
Whether |
10 |
20000 |
<=10 |
Whether |
Ideas
Consider the case of a tree root.
Set Sum[i] Indicates the number of points dis%4=i in the subtrees tree before S-1, and TMP represents the current S subtree.
Once DFS find out the cumulative answer after DIS.
It is important to note that the point pair is counted two times and the road length 0 counts as a multiple of 4.
Code
1#include <cstdio>2#include <vector>3#include <queue>4#include <cstring>5#include <iostream>6#include <algorithm>7 #definefor (A,B,C) for (int a= (b); a<= (c); a++)8 using namespacestd;9 Ten Const intN =20000+Ten; One A structEdge { - intv,w; -Edge (intv=0,intw=0): V (v), W (w) {} the }; -Vector<edge>G[n]; - intN,m,k,ans; - intRoot,size,siz[n],dis[n],f[n],vis[n]; + - intgcdintXintY) {returny==0? X:GCD (y,x%y); } + A voidGetroot (intUintFA) { atsiz[u]=1; f[u]=0; - for(intI=0; I<g[u].size (); i++) { - intv=g[u][i].v; - if(V!=FA &&!)Vis[v]) { - Getroot (v,u); -siz[u]+=Siz[v]; in if(Siz[v]>f[u]) f[u]=Siz[v]; - } to } +F[u]=max (f[u],size-Siz[u]); - if(F[u]<f[root]) root=u; the } * inttmp[4],sum[4]; $ voidDfsintUintFA) {Panax Notoginsengtmp[dis[u]]++; - for(intI=0; I<g[u].size (); i++) { the intv=g[u][i].v; + if(V!=FA &&!)Vis[v]) { Adis[v]= (DIS[U]+G[U][I].W)%4; the DFS (v,u); + } - } $ } $ voidSolveintu) { -memset (SUM,0,sizeof(sum)); -vis[u]=1; sum[0]=1; the for(intI=0; I<g[u].size (); i++) { - intv=g[u][i].v;Wuyi if(!Vis[v]) { thedis[v]=g[u][i].w%4; - DFS (v,u); Wu for(intj=0;j<4; j + +) -ans+=tmp[j]*sum[(4-J)%4]; About for(intj=0;j<4; j + +) $sum[j]+=tmp[j],tmp[j]=0; - } - } - for(intI=0; I<g[u].size (); i++) { A intv=g[u][i].v; + if(!Vis[v]) { theSIZE=SIZ[V]; root=0; -Getroot (v,-1); Solve (root); $ } the } the } the voidReadint&x) { the CharC=getchar ();intf=1; x=0; - while(!isdigit (c)) {if(c=='-') c=-1; C=GetChar ();} in while(IsDigit (c)) x=x*Ten+c-'0', c=GetChar (); thex*=F; the } About intMain () { the //freopen ("in.in", "R", stdin); the //freopen ("Out.out", "w", stdout); the while(Read (n), n!=0) { +ans=0; -for (I,0, N) g[i].clear (); thememset (Vis,0,sizeof(Vis));Bayi intu,v,w; thefor (I,1, N-1) { the Read ( u), read (v), read (w); - G[u].push_back (Edge (v,w)); - G[v].push_back (Edge (u,w)); the } theroot=0; f[0]=1e9; Size=N; theGetroot (1,-1), solve (root); the intB=n*n; ans=ans*2+N; - intGc=gcd (ans,b); theprintf"%d/%d\n", ans/gc,b/GC); the } the return 0;94}
Point Division treatment Exercise: not virtual is to AK