不虚就是要AK(czyak.c/.cpp/.pas)  2s 128M  by zhb

czy很火。因为又有人说他虚了。为了证明他不虚,他决定要在这次比赛AK。

现在他正在和别人玩一个游戏:在一棵树上随机取两个点,如果这两个点的距离是4的倍数,那么算czy赢,否则对方赢。现在czy想知道他能获胜的概率。

*最终输出的概率要求分数的分子和分母的和尽量小且非负数

本题多组数据。对于每组数据:

第一行一个数n,表示树上的节点个数

接下来n-1条边a,b,c描述a到b有一条长度为c的路径

当n=0时表示读入结束

数据组数不超过10。无部分分

输入数据

5

1 2 1

1 3 2

1 4 1

2 5 3

0

输出数据

7/25

数据范围

数据点

n的规模

数据组数

随机生成数据

1

200

1

2

200

1

3

200

<=3

4

2000

<=3

5

2000

<=3

6

2000

<=5

7

20000

<=5

8

20000

<=5

9

20000

<=10

10

20000

<=10


这题其实跟找距离=K的点对有多少个是一样的,我们把距离全部不断mod4就可以了。

然后就是点分治。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N=;
int n,len,ans;
int v[],t[],d[N],first[N],mark[N],size[N];
struct node{
int x,y,d,next;
}a[*N]; void ins(int x,int y,int d)
{
a[++len].x=x;a[len].y=y;a[len].d=d;
a[len].next=first[x];first[x]=len;
} int gcd(int x,int y)
{
if(y==) return x;
return gcd(y,x%y);
} void find_root(int x,int fa,int tot,int &root)
{
size[x]=;
bool bk=;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa || mark[y]) continue;
find_root(y,x,tot,root);
size[x]+=size[y];
if(*size[y]>tot) bk=;
}
if(bk && *(tot-size[x])<=tot) root=x;
} void DFS(int x,int fa)
{
int now=((-d[x])%+)%;
ans+=v[now];
t[d[x]]++;
size[x]=;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(mark[y] || y==fa) continue;
d[y]=(d[x]+a[i].d)%;
DFS(y,x);
size[x]+=size[y];
}
} void dfs(int x,int tot)
{
find_root(x,,tot,x); memset(v,,sizeof(v));
mark[x]=;d[x]=;v[]++; for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(mark[y]) continue;
d[y]=d[x]+a[i].d;
memset(t,,sizeof(t));
DFS(y,x);
for(int j=;j<;j++) v[j]+=t[j];
}
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(mark[y]) continue;
dfs(y,size[y]);
}
} int main()
{
freopen("a.in","r",stdin);
// freopen("czyak.in","r",stdin);
// freopen("czyak.out","w",stdout);
while()
{
scanf("%d",&n);
if(!n) break;
ans=;len=;
memset(mark,,sizeof(mark));
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y,d;
scanf("%d%d%d",&x,&y,&d);
d%=;
ins(x,y,d);
ins(y,x,d);
}
// for(int i=1;i<=len;i+=2) printf("%d --> %d %d\n",a[i].x,a[i].y,a[i].d);
dfs(,n);
int fz=*ans+n,fm=n*n;
int g=gcd(fz,fm);
fz/=g;fm/=g;
printf("%d/%d\n",fz,fm);
}
return ;
}
05-11 18:06