【HDU - 2376】Average distance (樹上任意兩點之間的距離之和的平均值、計算結點的貢獻度)
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 (d 01 + d 02 + d 03 + d 04 + d 12 +d 13 +d 14 +d 23 +d 24 +d 34)/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
解題報告:
就是求出樹上任意兩點間的距離的和,再求平均值。這樣只要知道每個邊走過幾次,用次數乘上這條邊的權值,再把所有邊加和,除以路徑數就可以。首先,關於路徑數,我覺得就像一個有 N個點的完備圖,這個圖中邊的數量,就是這N個點形成的樹,樹中任意兩點組成的邊的數量
ac程式碼:
#include<stdio.h>
#include<iostream>
#include<map>
#include<vector>
#include<string.h>
#define ll long long
#define mod 1000000007
using namespace std;
const int MAXN=2e5+10;
struct edge{
int y;
int w;
edge(){}
edge(int y,int w):y(y),w(w){}
};
int n;
vector<edge> vv[MAXN];
ll ans;
ll dp[MAXN];
void dfs(int x,int f)
{
int ed=vv[x].size();
for(int i=0;i<ed;i++)
{
edge v=vv[x][i];
if(v.y==f)
continue;
dfs(v.y,x);
dp[x]+=dp[v.y];
ans+=dp[v.y]*(n-dp[v.y])*v.w;
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
int u,v,w;
ans=0;
for(int i=0;i<n;i++)
{
vv[i].clear();
dp[i]=1;
}
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&u,&v,&w);
vv[u].push_back(edge(v,w));
vv[v].push_back(edge(u,w));
}
dfs(0,-1);
printf("%lf\n",ans*2.0/n/(n-1));
}
return 0;
};