这题主要是求任意两点之间的距离之和。首先通过枚举起点终点来求的话是O(N^2),会超时的,这题要换种思路,通过算每条边的贡献来得到任意两点之间的距离之和,每条边的贡献就是其2端的点数的乘积再乘以对应的边权,求每条边2端的点数就用dfs即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
#define ll long long
struct node
{
int v;
ll w;
node(int vv,ll ww)
{
v=vv;
w=ww;
}
};
vector<node>g[maxn];
ll ans,num[maxn];//num[i]表示子树i对应的节点的个数
int n;
void dfs(int now,int fa)
{
num[now]=1;
for(int i=0;i<g[now].size();i++)
{
int v=g[now][i].v;
ll w=g[now][i].w;
if(v==fa) continue;
dfs(v,now);
num[now]+=num[v];
ans+=w*(n-num[v])*num[v];
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
g[i].clear(),num[i]=0;
for(int i=1;i<=n-1;i++)
{
int u,v;
ll w;
scanf("%d %d %lld",&u,&v,&w);
g[u].push_back(node(v,w));
g[v].push_back(node(u,w));
}
dfs(0,-1);
int tmp=n*(n-1)/2;
printf("%.6lf
",ans*1.0/tmp);
}
return 0;
}