冲刺NOIP2015提高组复赛模拟试题(五)2.道路修建

2.道路修建

 

描述 Description

liouzhou_101最悲痛的回忆就是NOI2011的道路修建,当时开了系统堆栈,结果无限RE…

出于某种报复心理,就把那题神奇了一下:

在 Z星球上有N个国家,这N个国家之间只能建造N-1条道路且全部建完这N-1条道路后这N个国家相互连通,修建每条道路都有相应的花费。但是他们都很吝啬,于是决定只随机选出两个不同的国家(为了国家的平等,当然这两个国家是无顺序可言的),建造该建造的道路,使得这两个国家相互连通,自然费用越少越 好。然后问你,在所有情况中,修建道路花费的平均值。

假若您认为本题题目叙述太渣,那就形象地描述一遍:给出一棵边上带权的树,求任意两个不同的点的距离的期望值。

 

 

输入格式 InputFormat

第一行包括一个正整数N,N表示国家的数量。

接下来N-1行每行包括三个正整数x、y和w,表示国家x和国家y之间有一条花费为w的道路。

 

 

输出格式 OutputFormat

仅一行,包含一个最简分数,格式为A/B,详见样例。

 

样例输入 SampleInput [复制数据]

4

1 2 1

1 3 1

1 4 1

样例输出 SampleOutput [复制数据]

3/2

数据范围和注释 Hint

对于这组测资,共存在6种情况:

①(1,2) 距离 1; ②(1,3) 距离 1;

③(1,4) 距离 1; ④(2,3) 距离 2;

⑤(2,4) 距离 2; ⑥(3,4) 距离 2;

所以平均值为(1+1+1+2+2+2)/6=3/2。

 

30%的数据,满足n<=1,000;

50%的数据,满足n<=10,000;

100%的数据,满足1<=n<=100,000,1<=w<=1,000。

 

 

时间限制 TimeLimitation

1s
解:随便找个点dfs,假设节点y下有s[y]个点(包括y),他的父节点为t,通过这条路就有s[y]*(n-s[y])次,统计一下即可。
注意:全开long long
来源:“扫地”杯III NOIP2012模拟赛 day1 第二题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define sc(x) scanf("%d",&x)
 7 #define scl(x) scanf("%lld",&x)
 8 #define man 101000
 9 #define ll long long
10 using namespace std;
11 ll n;
12 struct edge
13 {
14     ll next,to,dis;
15     }e[man*2];
16 ll s[man];
17 bool vis[man];
18 ll sum=0;
19 ll head[man*2],num=0;
20 void add(int from,int to,int dis)
21 {
22     e[++num].next=head[from];
23     e[num].to=to;
24     e[num].dis=dis;
25     head[from]=num;
26     }
27 ll gcd(ll a,ll b)
28 {
29     if(b==0)
30         return a;
31     else return gcd(b,a%b);
32     }
33 void dfs(ll t)
34 {
35     s[t]=1;vis[t]=1;
36     for(int i=head[t];i;i=e[i].next)
37     {
38         ll to=e[i].to;
39         if(!vis[to])
40         {
41             dfs(to);
42             sum+=e[i].dis*(n-s[to])*s[to];
43             s[t]+=s[to];
44             }
45         }
46     }
47 int main()
48 {   freopen("road.in","r",stdin);
49     freopen("road.out","w",stdout);
50     scl(n);
51     for(int i=1;i<n;i++)
52     {
53         int x,y,z;
54         sc(x);sc(y);sc(z);
55         add(x,y,z);
56         add(y,x,z);
57         }
58     dfs(1);
59     n=n*(n-1)/2;
60     if(n==0)
61         n=1;
62     ll ans=gcd(sum,n);
63     printf("%lld/%lld",sum/ans,n/ans);
64     return 0;
65     }

 

posted @ 2017-08-27 22:16  Slager_Z  阅读(161)  评论(0编辑  收藏  举报
博客园 首页 私信博主 显示目录 隐藏目录 管理 动画