HDU-2376(树上统计,DFS)

2015-01-01 01:46:36

思路:简单的树上统计题目,计算出每条边对于答案的贡献即可。

  对于每条边,设该边一侧的子树大小为sz,那么被计算次数应该是:sz * (n - sz)

  总情况数为:在n个点里选2个,C(n,2)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <stack>
 9 #include <queue>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 #define lp (p << 1)
14 #define rp (p << 1|1)
15 #define getmid(l,r) (l + (r - l) / 2)
16 #define MP(a,b) make_pair(a,b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 typedef pair<int,int> pii;
20 const int INF = (1 << 30) - 1;
21 const int maxn = 10010;
22 
23 int T,n;
24 int first[maxn],next[maxn << 1],ver[maxn << 1],w[maxn << 1],ecnt;
25 int sz[maxn],total;
26 double ans;
27 
28 void Init(){
29     memset(first,-1,sizeof(first));
30     ecnt = 0;
31 }
32 
33 void Add_edge(int u,int v,int c){
34     next[++ecnt] = first[u];
35     ver[ecnt] = v;
36     w[ecnt] = c;
37     first[u] = ecnt;
38 }
39 
40 void Dfs(int p,int fa){
41     sz[p] = 1;
42     for(int i = first[p]; ~i; i = next[i]){
43         int v = ver[i];
44         if(v == fa) continue;
45         Dfs(v,p);
46         ans += (double)sz[v] * (n - sz[v]) * w[i] / total;
47         sz[p] += sz[v];
48     }
49 }
50 
51 int main(){
52     int a,b,c;
53     scanf("%d",&T);
54     while(T--){
55         Init();
56         scanf("%d",&n);
57         total = n * (n - 1) / 2;
58         for(int i = 1; i < n; ++i){
59             scanf("%d%d%d",&a,&b,&c);
60             Add_edge(a,b,c);
61             Add_edge(b,a,c);
62         }
63         ans = 0.0;
64         Dfs(0,-1);
65         printf("%.10f\n",ans);
66     }
67     return 0;
68 }

 

posted @ 2015-01-01 01:49  Naturain  阅读(168)  评论(0编辑  收藏  举报