先用prim算法求一次最小生成树,最小生成树用链式前向星储存起来,然后树形dp预处理,节点i到子树j的最小距离,每次访问改变一条边的值,删去这条边,这个最小生成树被分为两个子树,dfs求得连接这两个子树的最小权值边,将每次访问后的最小生成树权值加起来除以访问次数即得到平均值,
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
#include <string>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#include <cctype>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
#define MEM(a,b) memset(a,b,sizeof a)
#define CLR(a) memset(a,0,sizeof a);
const int inf = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
//#define LOCAL
int mp[3005][3005];
bool vis[3005];
int to[3005];
int dp[3005][3005];
bool flag[3005][3005];
int pnt[3005*2],nxt[3005*2],head[3005],cost[3005*2];
int n,m;
int tmp;
int cnt;
void addedge(int u,int v,int c){
pnt[cnt]=v;
nxt[cnt]=head[u];
cost[cnt]=c;
head[u]=cnt++;
}
int prime(){
int ans = 0;
CLR(vis);
vis[0]=1;
for(int i=1;i<n;i++){
to[i]=0;
}
for(int i=1;i<n;i++){
int mincost = inf;
int pos;
for(int j=0;j<n;j++){
if(!vis[j] && mincost > mp[to[j]][j]){
mincost = mp[to[j]][j];
pos = j;
}
}
if(mincost == inf)break;
ans += mincost;
vis[pos]=1;
flag[to[pos]][pos]=1;
flag[pos][to[pos]]=1;
addedge(to[pos],pos,mincost);
addedge(pos,to[pos],mincost);
for(int j=0;j<n;j++){
if(!vis[j] && mp[to[j]][j] > mp[pos][j])
to[j]=pos;
}
}
return ans;
}
int DP(int u,int pre,int root){
dp[root][u]=inf;
if(pre != root)dp[root][u]=mp[root][u];
for(int i=head[u];~i;i=nxt[i]){
int v = pnt[i];
if(v != pre){
dp[root][u] = min(dp[root][u],DP(v,u,root));
}
}
return dp[root][u];
}
int solve(int u,int pre,int tree){
int ans = dp[u][tree];
for(int i=head[u];~i;i=nxt[i]){
int v = pnt[i];
if(v!=pre){
ans = min(solve(v,u,tree),ans);
}
}
return ans;
}
int main()
{
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
while(cin >> n >>m && (n+m)){
double sum = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
mp[i][j]=inf;
flag[i][j]=0;
}
}
cnt = 0;
MEM(head,-1);
for(int i=1;i<=m;i++){
int u,v,c;scanf("%d%d%d",&u,&v,&c);
mp[u][v]=c;
mp[v][u]=c;
}
tmp = prime();
for(int i=0;i<n;i++){
DP(i,-1,i);
}
int q;scanf("%d",&q);
for(int i=1;i<=q;i++){
int u,v,c;
scanf("%d%d%d",&u,&v,&c);
if(!(flag[u][v])){
sum += tmp;
}
else{
int x = solve(u,v,v);
sum += min(tmp-mp[u][v]+c,tmp-mp[u][v]+x);
}
}
printf("%.4lf\n",sum/q);
}
return 0;
}