Codeforces 280C. Game on Tree

题目描述

乍一看每一个点被选它自己而被染色到的概率都是1/n,但仔细想想就会发现,某一个点对答案的贡献只与这个点有多少个祖先有关。

因为如果这个点会被选到,当且仅当它的所有祖先都没有被选到(题目中说会将选到的点所在的整棵子树都染成黑色),所有每个点被选而被染色的概率为1/deep[i]。

又因为每次选的代价为一,所以每个点对答案的贡献就是1/deep[i]。

#include<complex>
#include<cstdio>
using namespace std;
const int N=1e5+7;
struct node{
    int v,nxt;
}e[N<<1];
int n,Enum;
double ans;
int front[N],deep[N];
int qread()
{
    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;
}
void Insert(int u,int v)
{
    e[++Enum].v=v;
    e[Enum].nxt=front[u];
    front[u]=Enum;
}
void dfs(int x,int from)
{
    for(int i=front[x];i;i=e[i].nxt)
    {
        if(e[i].v==from)continue;
        deep[e[i].v]=deep[x]+1;
        dfs(e[i].v,x);
    }
}
int main()
{
    scanf("%d",&n);
    int u,v;
    for(int i=1;i<n;i++)
    {
        u=qread();v=qread();
        Insert(u,v);Insert(v,u);
    }
    deep[1]=1;
    dfs(1,0);
    for(int i=1;i<=n;i++)
        ans+=1.0/deep[i];
    printf("%.20llf\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/LeTri/p/9157166.html

时间: 2024-10-31 13:07:16

Codeforces 280C. Game on Tree的相关文章

Codeforces.280C.Game on Tree(期望)

题目链接 参考:浅谈期望的线性性(可加性) Codeforces 280C Game on Tree 概率dp 树上随机删子树 求删完次数的期望(这个的前半部分分析并没有看..) \(Description\) 给你一棵有\(n\)个白点的有根树,每次随机选择一个点,将它和它的子树中所有点染黑. 问期望操作多少次后所有点都被染黑? \(Solution\) 期望好玄啊..(好吧是我太弱) 因为概率具有可加性,一棵树可以分解为多棵子树,而子树分解的最终状态就是点,所以我们可以计算每个点的期望操作次

Codeforces 280C Game on Tree 概率dp 树上随机删子树 求删完次数的期望

题目链接:点击打开链接 题意:给定n个点的一棵树 每次操作随机选任意一个点,把这个点和这个点的子树删去. 当把所有点删去则停止. 问操作次数的期望. 题解引用自:点击打开链接 删除的规则拥有一个非常好的性质:对于任意(u,v),选择u会导致删除v,那么选择u会删除的点集合一定包含选择了v以后会删除的点集合. 我们考虑换一种方式来实现删除的过程: 产生一个随机的1-n的排列P,从前往后依次尝试删除这些点,如果当前点已经被删除,就什么都不干,否则把次数+1,删除这个点以及他的所有后代. 通过这种方式

Codeforces 461B Appleman and Tree(木dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量.保证每一个联通分量有且仅有1个黑色节点.问有多少种切割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的切割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include &l

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 461B Appleman and Tree(树形dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每个节点的父亲节点,以及每个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量,保证每个联通分量有且仅有1个黑色节点.问有多少种分割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的分割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include <c

Educational Codeforces Round 25 G. Tree Queries

题目链接:Educational Codeforces Round 25 G. Tree Queries 题意: 给你一棵树,一开始所有的点全是黑色,有两种操作. 1 x 将x这个点变为黑色,保证第一个操作是这个. 2 x 询问x到任意黑色的点的简单路径上的最小节点编号. 题解: 首先将一个变为黑色的点当成树根,然后dfs一下,预处理出所有点的答案. 然后开一个变量记录一下当前变黑的点的答案cur=min(cur,dp[x]). 每次询问的时候答案就是min(cur,dp[x]). 如果觉得很神

CodeForces 396C On Changing Tree

On Changing Tree Time Limit: 2000ms Memory Limit: 262144KB This problem will be judged on CodeForces. Original ID: 396C64-bit integer IO format: %I64d      Java class name: (Any) You are given a rooted tree consisting of n vertices numbered from 1 to

Codeforces 348B:Apple Tree(DFS+LCM+思维)

http://codeforces.com/contest/348/problem/B 题意:给一棵树,每个叶子结点有w[i]个苹果,每个子树的苹果数量为该子树所有叶子结点苹果数量之和,要使得每个结点的各个子树苹果数量相等,求至少需要拿走的苹果数量. 思路:一开始以为只要使得所有子树之和相同就行了. 1 void dfs(int u, int fa) { 2 int num = 0, mi = INF; 3 for(int i = head[u]; ~i; i = edge[i].nxt) {

【CodeForces】343D Water tree (线段树好题!还未弄懂)

/* 此题的方法除了用线段树求子树,通过标记父亲,更新儿子的方法,来更新祖先,学习了. 对于建树的方法由于并没有说明父亲与儿子的顺序,所以需要通过两次添加. 并且pre变量可以获得父亲的位置,还未弄懂! */ #define _CRT_SECURE_NO_WARNINGS #include<cstring> #include<cstdio> #include<iostream> #include<algorithm> using namespace std;