算出每个边被选中概率,然后每条边权×概率,和即为答案。
一共有C(n,3)种选法,每条边下边有down[x]个,上面有n-down[x]个,选取该边方法有down[x]*(n-down[x])*(n-2) thinking==
然后初以总选法就是概率。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int now=0,head[200005],next[200005],point[200005]; 6 int down[100005],l[100005],r[100005],w[100005],num[100005]; 7 double g[100005]; 8 void add(int u,int v,int w) 9 { 10 next[++now]=head[u]; 11 head[u]=now; 12 point[now]=v; 13 } 14 void dfs(int pre,int u) 15 { 16 down[u]=1; 17 for (int i=head[u];i;i=next[i]) 18 { 19 int v=point[i]; 20 if (v==pre) continue; 21 dfs(u,v); 22 down[u]+=down[v]; 23 } 24 } 25 int main() 26 { 27 int t1,t2,n,i,q,tmp; 28 double sum,ans; 29 scanf("%d",&n); 30 memset(head,0,sizeof(head)); 31 for (i=1;i<n;i++) 32 { 33 scanf("%d%d%d",&l[i],&r[i],&w[i]); 34 add(l[i],r[i],w[i]); 35 add(r[i],l[i],w[i]); 36 } 37 sum=1.0*n*(n-1)*(n-2)/6.0; 38 memset(down,0,sizeof(down)); 39 dfs(0,1); 40 memset(num,0,sizeof(num)); 41 for (i=1;i<=n;i++) 42 num[i]=down[i]*(n-down[i])*(n-2); 43 ans=0.0; 44 for (i=1;i<n;i++) 45 { 46 tmp=min(down[l[i]],down[r[i]]);//thinking== 47 g[i]=1.0*tmp*(n-tmp)*(n-2); 48 ans=ans+w[i]*g[i]/sum; 49 } 50 scanf("%d",&q); 51 while (q--) 52 { 53 scanf("%d%d",&t1,&t2); 54 ans-=1.0*(w[t1]-t2)*g[t1]/sum; 55 w[t1]=t2; 56 printf("%lf\n",ans); 57 } 58 return 0; 59 }