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 }