「CF500D」New Year Santa Network
题解
树形dp得出每条边对答案的贡献次数
选取的三个点,有两个在这条边的一边,一个在另一边的方案数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<set> #include<iomanip> #include<ctime> #include<vector> #include<queue> #include<algorithm> #include<map> #include<cmath> #define eps 1e-6 #define inf 1000000000 #define pa pair<int,int> #define ll long long using namespace std; int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x; } ll n,m,cnt=1; double ans,tot; struct edge{ int from,to,next; ll v,T; }e[200005]; ll size[100005],last[100005],deep[100005]; void insert(int u,int v,int w) { e[++cnt].to=v;e[cnt].from=u;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w; e[++cnt].to=u;e[cnt].from=v;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=w; } void dfs(int x,int fa) { size[x]=1; for(int i=last[x];i;i=e[i].next) if(e[i].to!=fa) { deep[e[i].to]=deep[x]+1; dfs(e[i].to,x); size[x]+=size[e[i].to]; } } int main() { n=read();tot=n*(n-1)*(n-2)/6.0; for (int i=1;i<n;i++) { int u=read(),v=read(),w=read(); insert(u,v,w); } dfs(1,0); for (int i=2;i<=cnt;i+=2) { int now=i/2,x=e[i].from,y=e[i].to; if(deep[x]>deep[y])swap(x,y); ll s1=n-size[y],s2=size[y]; e[i].T+=s1*s2*(s2+s1-2); ans+=e[i].T*e[i].v; } m=read(); for (int i=1;i<=m;i++) { int x=read(),y=read(); ll now=x*2; ans-=(e[now].v-y)*e[now].T; e[now].v=y; printf("%.9lf\n",(double)ans/tot); } return 0; } |
Subscribe