cf 500 D. New Year Santa Network

直接按边分,2个点在边的一边,1个在另一边,组合出来就是这个边对答案的贡献,权值换了就再重新算个数而已。

 1 #include <bits/stdc++.h>
 2 #define LL long long
 3 using namespace std;
 4 inline int ra()
 5 {
 6     int x=0,f=1; char ch=getchar();
 7     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
 8     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
 9     return x*f;
10 }
11 LL n,m,cnt=1;
12 double ans,tot;
13 struct edge{
14     int from,to,next;
15     LL v,T;
16 }e[200005];
17 LL size[100005],head[100005],deep[100005];
18 void insert(int x, int y, int v)
19 {
20     e[++cnt].next=head[x]; e[cnt].from=x; e[cnt].to=y; e[cnt].v=v; head[x]=cnt;
21 }
22 void dfs(int x, int fa)
23 {
24     size[x]=1;
25     for (int i=head[x];i;i=e[i].next)
26     {
27         if (e[i].to==fa) continue;
28         deep[e[i].to]=deep[x]+1;
29         dfs(e[i].to,x);
30         size[x]+=size[e[i].to];
31     }
32 }
33 int main(int argc, char const *argv[])
34 {
35     n=ra(); tot=n*(n-1)*(n-2)/6.0;
36     for (int i=1; i<n; i++)
37     {
38         int x=ra(),y=ra(),v=ra();
39         insert(x,y,v); insert(y,x,v);
40     }
41     dfs(1,0);
42     for (int i=2; i<=cnt; i+=2)
43     {
44         int now=i/2,x=e[i].from,y=e[i].to;
45         if (deep[x]>deep[y]) swap(x,y);
46         LL s1=n-size[y],s2=size[y];
47         e[i].T+=s1*s2*((LL)n-2);
48         ans+=e[i].T*e[i].v;
49     }
50     m=ra();
51     for (int i=1; i<=m; i++)
52     {
53         int x=ra(),y=ra();
54         LL now=x*2;
55         ans-=(e[now].v-y)*e[now].T;
56         e[now].v=y;
57         printf("%.10lf
",(double)ans/tot);
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/ccd2333/p/6512060.html