codeforces New Year Santa Network

来源:互联网 发布:win7系统更新失败知乎 编辑:程序博客网 时间:2024/06/16 02:31

题目意思,给你一棵树,然后给你N-1条双向边,现在有3个圣诞老人会选树3个点作为放礼物的仓库。用dis(u,v)表示u->v的距离 ,假设建立3个仓库分别为X,Y,Z,那么会花费

dis(X,Y)+dis(X,Z)+dis(Y,Z)的钱,圣诞老人很懒,他们随机的选择3个点,现在需要定义这个花费的期望值,然后由于城市每年都有会修一条路,新的路会变短,现在有个Q个查询

每次修改一条边的路径(一定是变短),问你这个花费期望值是多少,N和Q都是 10^5




#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<vector>#include<map>using namespace std;#define NN 100010#define LL long longint m1[NN],m2[NN],L[NN];vector<int>edge[NN];map< pair<int,int> ,int>mp;int dp[NN],n;LL num[NN];double sum;int fun(int u,int v){    if(u>v)        swap(u,v);    return mp[make_pair(u,v)];}int dfs(int u,int fa){    dp[u]=1;    int ss=edge[u].size();    for(int i=0;i<ss;i++)    {        int v=edge[u][i];        if(v==fa)            continue;        dp[u]+=dfs(v,u);    }    if(u!=fa)    {        int id=fun(u,fa);        LL tmp=dp[u];        LL tmp1=(LL)n-(LL)dp[u];        num[id]=tmp*tmp1;    }    return dp[u];}int main(){    while(scanf("%d",&n)!=EOF)    {        mp.clear();        for(int i=0;i<=n;i++)        {            edge[i].clear();        }        for(int i=1;i<n;i++)        {            scanf("%d %d %d",&m1[i],&m2[i],&L[i]);            if(m1[i]>m2[i])                swap(m1[i],m2[i]);            mp[ make_pair(m1[i],m2[i]) ]=i;            edge[m1[i]].push_back(m2[i]);            edge[m2[i]].push_back(m1[i]);        }        dfs(1,1);        sum=0.0;        for(int i=1;i<n;i++)        {            double t1=double(num[i]);            double t2=double(L[i]);            sum=sum+t1*t2;        }        double tt=double(n);        tt=tt*(tt-1.0);        int q;        scanf("%d",&q);        while(q--)        {            int id,len;            scanf("%d %d",&id,&len);            sum=sum-L[id]*num[id]*1.0+len*num[id]*1.0;            L[id]=len;            printf("%lf\n",sum*6.0/tt);        }    }    return 0;}


0 0
原创粉丝点击