zoukankan      html  css  js  c++  java
  • hdu 2736 Average distance

    传送门

    Average distance

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 682    Accepted Submission(s): 244
    Special Judge


    Problem Description
    Given a tree, calculate the average distance between two vertices in the tree. For example, the average distance between two vertices in the following tree is (d01 + d02 + d03 + d04 + d12 +d13 +d14 +d23 +d24 +d34)/10 = (6+3+7+9+9+13+15+10+12+2)/10 = 8.6.



     
    Input
    On the first line an integer t (1 <= t <= 100): the number of test cases. Then for each test case:

    One line with an integer n (2 <= n <= 10 000): the number of nodes in the tree. The nodes are numbered from 0 to n - 1.

    n - 1 lines, each with three integers a (0 <= a < n), b (0 <= b < n) and d (1 <= d <= 1 000). There is an edge between the nodes with numbers a and b of length d. The resulting graph will be a tree.

     
    Output
    For each testcase:

    One line with the average distance between two vertices. This value should have either an absolute or a relative error of at most 10-6

     
    Sample Input
    1 5 0 1 6 0 2 3 0 3 7 3 4 2
     
    Sample Output
    8.6
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  2378 2379 2377 2380 2381 
     
     

    哎,思路想复杂了,其实蛮简单的:

    转一发题解:

    引:如果暴力枚举两点再求距离是显然会超时的。转换一下思路,我们可以对每条边,求所有可能的路径经过此边的次数:设这条边两端的点数分别为A和B,那 么这条边被经过的次数就是A*B,它对总的距离和的贡献就是(A*B*此边长度)。我们把所有边的贡献求总和,再除以总路径数N*(N-1)/2,即为最 后所求。

    每条边两端的点数的计算,实际上是可以用一次dfs解决的。任取一点为根,在dfs的过程中,对每个点k记录其子树包含的点数(包括其自身),设点数为a[k],则k的父亲一侧的点数即为N-a[k]。这个统计可以和遍历同时进行。故时间复杂度为O(n)。

    16447376 2016-03-06 09:40:59 Accepted 2376 312MS 4540K 2093 B C++ czy
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <stack>
     6 #include <cctype>
     7 #include <vector>
     8 #include <cmath>
     9 #include <map>
    10 #include <queue>
    11 
    12 #define ll long long
    13 #define N 10005
    14 #define eps 1e-8
    15 
    16 using namespace std;
    17 
    18 int T;
    19 double tot[N];
    20 double cou[N];
    21 double num;
    22 int n;
    23 
    24 struct PP
    25 {
    26     int to;
    27     double val;
    28 };
    29 
    30 vector<PP>Edge[N];
    31 
    32 PP te;
    33 
    34 void add_adge(int from,int to,double val)
    35 {
    36     te.to = to;te.val = val;
    37     Edge[from].push_back(te);
    38     te.to = from;te.val = val;
    39     Edge[to].push_back(te);
    40 }
    41 
    42 void dfs(int now,int fa)
    43 {
    44     unsigned int i;
    45     PP nt;
    46     cou[now] = 1;
    47     for(i = 0;i < Edge[now].size();i++){
    48         nt.to = Edge[now][i].to;
    49         nt.val = Edge[now][i].val;
    50         if(nt.to == fa){
    51             continue;
    52         }
    53         dfs(nt.to,now);
    54         tot[now] = tot[now] + tot[nt.to] + (n-cou[nt.to]) * cou[nt.to] * nt.val;
    55         cou[now] = cou[now] + cou[nt.to];
    56         //printf("  now = %d i=%d to=%d tot=%.6f cou=%.6lf
    ",now,i,nt.to,tot[now],cou[now]);
    57     }
    58     //printf(" i=%d tot=%.6f cou=%.6f
    ",now,tot[now],cou[now]);
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("in.txt","r",stdin);
    64     scanf("%d",&T);
    65     int i;
    66     int from,to;
    67     double val;
    68     for(int ccnt=1;ccnt<=T;ccnt++){
    69     //while(scanf("%lf%lf%lf%lf",&a[0],&a[1],&a[2],&a[3])!=EOF){
    70         scanf("%d",&n);
    71         memset(tot,0,sizeof(tot));
    72         memset(cou,0,sizeof(cou));
    73         num = 1.0 *n*(n-1)/2;
    74         for(i=0;i<=n;i++){
    75             Edge[i].clear();
    76         }
    77         for(i=1;i<=n-1;i++){
    78             scanf("%d%d%lf",&from,&to,&val);
    79             add_adge(from,to,val);
    80         }
    81         dfs(0,-1);
    82         //for(i=0;i<n;i++){
    83          //   for(int j=0;j<Edge[i].size();j++){
    84          //       printf(" i=%d to=%d val=%.6lf
    ",i,Edge[i][j].to,Edge[i][j].val);
    85          //   }
    86        // }
    87         for(i=0;i<n;i++){
    88             //printf(" i=%d tot=%.6f cou=%.6f
    ",i,tot[i],cou[i]);
    89         }
    90         printf("%lf
    ",tot[0]/num);
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    第十二周作业
    第九周作业
    第八周作业
    第七周作业
    第六周作业
    参考博文地址
    第五周作业
    用例设计思路
    测试方法的四大金刚
    网络模型及访问过程
  • 原文地址:https://www.cnblogs.com/njczy2010/p/5246583.html
Copyright © 2011-2022 走看看