Average distance hdu 2376
Average distance
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1765 Accepted Submission(s): 647
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
这是一道很简单、经典的题目
让你求出所有点路径之间的距离平均值。
我们可以找任意一条边(红色的边) ,开始算这条边的贡献,可以得到在这条边的左边有3个点,右边4个,那这条边就再结果中做出了 3 * 4 * val(2,5) 的贡献 ,其他边也可以用类似的方法算出贡献来 ,dfs得到一边点的集合个数即可
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
vector<vector<P> >v;
const int maxn = 2e6;
ll ans[maxn];
int n;
ll val[maxn];
ll sum[maxn],vis[maxn];
int dfs(ll x,ll fa) {
ll s = 0;
// cout << x << endl;
for(auto const dd:v[x]) {
ll d = dd.first;
ll c = dd.second;
if(d != fa) {
dfs(d,x);
vis[x] += vis[d];
sum[x] += vis[d] * c * (n - vis[d]);
}
}
}
int main() {
int t;
cin >> t;
while(t--) {
cin >> n ;
v.clear();
v.resize(n + 500);
memset(sum,0,sizeof(sum));
for(int i = 0; i <= n; i++) vis[i] = 1;
for(int i = 1; i < n; i++) {
int u,vv,c;
cin >> u >> vv >> c;
v[vv].push_back(P(u,c));
v[u].push_back(P(vv,c));
}
dfs(1,-1);
ll anss = 0;
for(int i = 0; i <= n; i++) anss += sum[i];
double ans = 0;
// cout << anss << endl;
ans = anss / (double)(n * (n - 1) / 2);
printf("%.6f\n",ans);
}
return 0;
}
//9
//1 1 2 4 5 6 7 5
//1 -1 -1 3 -1 5 -1 7 7
// 9