题目链接
跑一遍mst,同时构造出树,再在树上跑一遍dfs,就可以计算出任意2点之间的距离了
#include<bits/stdc++.h>
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
#define LL long long
#define pb push_back
const int maxn = 1e5+200;
const int inf = 1 << 23;
int n,m;
struct Edge{
int x,y,w;
bool operator<(const Edge a) const{
return w<a.w;
}
}G[maxn*10];
int f[maxn];
void init(int n){
for(int i=0;i<=n;i++){
f[i]=i;
}
}
int find(int x){
if(f[x]==x)return x;
return f[x]=find(f[x]);
}
void merge(int x,int y){
x=find(x);y=find(y);
if(x==y)return ;
f[x]=y;
}
bool same(int x,int y){
return find(x)==find(y);
}
struct Edge2{
int to,w;
};
vector<Edge2> G2[maxn];
LL sum[maxn];
double ret ;
void dfs(int x,int fa){
sum[x]=1;
for(int i=0;i<G2[x].size();i++){
int y = G2[x][i].to;
int w = G2[x][i].w;
if(y==fa)continue;
dfs(y,x);
sum[x]+=sum[y];
ret+=1.0*sum[y]*(n-sum[y])*w;
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
for(int i=0;i<maxn;i++){
G2[i].clear();
sum[i]=0;
}
scanf("%d%d",&n,&m);
init(n);
for(int i=0;i<m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
G[i]=(Edge){x,y,z};
}
sort(G,G+m);
LL ans=0;
for(int i=0;i<m;i++){
if(same(G[i].x,G[i].y))continue;
merge(G[i].x,G[i].y);
ans+=G[i].w;
G2[G[i].x].pb((Edge2){G[i].y,G[i].w});
G2[G[i].y].pb((Edge2){G[i].x,G[i].w});
}
ret = 0;
dfs(1,-1);
printf("%lld %.2lf\n",ans,ret/(n-1)/n*2);
}
return 0;
}