codeforces 500D - New Year Santa Network (树形DP+组合数学)

题目地址:http://codeforces.com/contest/500/problem/D

这题是要先求出每条边出现的次数,然后除以总次数,这样期望就求出来了。先用树形DP求出每个边左右两端总共有多少个点,然后用组合数学公式就可以推出来了。

代码如下:

#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
int vis[110000];
int head[110000], cnt, n;
LL fx[110000], fy[110000], dp[110000], w[110000];
struct node {
        int u, v, w, id, next;
}edge[210000];
void add(int u, int v, LL w, int id)
{
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].id=id;
        edge[cnt].next=head[u];
        head[u]=cnt++;
}
void dfs(int u)
{
        dp[u]=1;
        vis[u]=1;
        for(int i=head[u]; i!=-1; i=edge[i].next) {
                int v=edge[i].v;
                if(vis[v]) continue ;
                dfs(v);
                //printf("---%.2f\n",ans);
                fx[edge[i].id]=dp[v];
                fy[edge[i].id]=n-dp[v];
                dp[u]+=dp[v];
        }
}
void init()
{
        memset(head,-1,sizeof(head));
        cnt=0;
        memset(vis,0,sizeof(vis));
}
int main()
{
        int i, j, u, v, m, k, t;
        scanf("%d",&n);
        init();
        for(i=0; i<n-1; i++) {
                scanf("%d%d%I64d",&u,&v,&w[i]);
                add(u,v,w[i],i);
                add(v,u,w[i],i);
        }
        dfs(1);
        double ans=0;
        for(i=0;i<n;i++){
                ans+=fx[i]*(fx[i]-1)*fy[i]*w[i]+fx[i]*(fy[i]-1)*fy[i]*w[i];
        }
        scanf("%d",&m);
        while(m--) {
                scanf("%d%d",&k,&t);
                k--;
                //printf("--%.3f\n",ans);
                ans-=fx[k]*(fx[k]-1)*fy[k]*(w[k]-t)+fx[k]*fy[k]*(fy[k]-1)*(w[k]-t);
                //printf("---%.3f\n",ans);
                w[k]=t;
                printf("%.9f\n",ans/n/(n-1)/(n-2)*6);
        }
        return 0;
}
时间: 2024-10-28 16:44:35

codeforces 500D - New Year Santa Network (树形DP+组合数学)的相关文章

Codeforces 500D New Year Santa Network(树 + 计数)

D. New Year Santa Network time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n - 1 roads,

codeforces 161D - Distance in Tree(树形dp)

题目大意: 求出树上距离为k的点对有多少个. 思路分析: dp[i][j] 表示 i 的子树中和 i 的距离为 j 的点数有多少个.注意dp[i] [0] 永远是1的. 然后在处理完一颗子树后,就把自身的dp 更新. 更新之前更新答案. 如果这颗子树到 i 有 x 个距离为j的.那么答案就要加上 dp[i] [ k-j-1] * x; #include <iostream> #include <cstdio> #include <cstring> #include &l

CodeForces 219D.Choosing Capital for Treeland (树形dp)

题目链接: http://codeforces.com/contest/219/problem/D 题意: 给一个n节点的有向无环图,要找一个这样的点:该点到其它n-1要逆转的道路最少,(边<u,v>,如果v要到u去,则要逆转该边方向)如果有多个这样的点,则升序输出所有 思路: 看了三篇博客,挺好的 http://blog.csdn.net/chl_3205/article/details/9284747 http://m.blog.csdn.net/qq_32570675/article/d

SGU 149. Computer Network( 树形dp )

题目大意:给N个点,求每个点的与其他点距离最大值 很经典的树形dp...很久前就想写来着...看了陈老师的code才会的...mx[x][0], mx[x][1]分别表示x点子树里最长的2个距离, dfs一遍得到. mx[x][2]表示从x的父亲到x的最长路径长度, 也是dfs一遍得到(具体看代码).最后答案就是max(mx[x][0], mx[x][2]). 时间复杂度O(N) ----------------------------------------------------------

Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_dis[i],维护非子树节点中距离该点的最大值fa_dis[i]; 2.对于每个节点维护它最大的三个儿子节点的son_dis; 3.维护up[i][j]和down[i][j]数组,这个类似倍增lca里边的fa[i][j],up[i][j]代表的含义是从第j个点向上到它的第2^i个父节点这条链上的点除了该

Codeforces 671D. Roads in Yusland(树形DP+线段树)

调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果我们枚举每条路去转移,会发现这条路沿线上的其他子树的答案难以统计,那怎么办呢,我们可以让这条路向上回溯的时候顺便记录一下,于是有$val[i]$表示必修i这条路,并且修完当前子树的最小代价. 则有转移$dp[x]=min(val[j])$,且$j$这条路必须覆盖$x$. $val[i]=(\sum

codeforces 337D D. Book of Evil(树形dp)

题目链接: codeforces 337D 题目大意: 给出一棵树,给出感染物的感染范围,给出一些已经确定被感染的点,问感染物可能放置的点的个数. 题目分析: 定义状态dp[i]代表某个点到达离它最远的确定的感染点的距离. 然后我们首先dfs一遍,求得以1为根的树,每个点到子树中的感染点的最大距离,然后再dfs一遍,求得dp[i]所要求的值,利用一个dd[i]数组表示第i点的父亲,除了自己及以自己为根的子树的点的感染点到自己的最远距离. 然后处理出来每个点儿子的前缀和后缀的最大值,然后利用dd就

CF 500D New Year Santa Network tree 期望 好题

New Year is coming in Tree World! In this world, as the name implies, there are n cities connected by n - 1 roads, and for any two distinct cities there always exists a path between them. The cities are numbered by integers from 1 to n, and the roads

Codeforces 815C. Karen and Supermarket【树形DP】

LINK 思路 首先发现依赖关系是一个树形的结构 然后因为直接算花多少钱来统计贡献不是很好 因为数组开不下 那就可以算一个子树里面选多少个的最小代价就可以了 注意统计贡献的时候用优惠券的答案只能在1号点进行统计 //Author: dream_maker #include<bits/stdc++.h> using namespace std; //---------------------------------------------- //typename typedef long lon