zoukankan      html  css  js  c++  java
  • CF696B Puzzles

    Description

    Barney lives in country USC (United States of Charzeh). USC has n cities numbered from 1 through n and n - 1 roads between them. Cities and roads of USC form a rooted tree (Barney’s not sure why it is rooted). Root of the tree is the city number 1. Thus if one will start his journey from city 1, he can visit any city he wants by following roads.

    Some girl has stolen Barney’s heart, and Barney wants to find her. He starts looking for in the root of the tree and (since he is Barney Stinson not a random guy), he uses a random DFS to search in the cities. A pseudo code of this algorithm is as follows:

    let starting_time be an array of length n 
    current_time = 0 
    dfs(v): 
    current_time = current_time + 1 
    starting_time[v] = current_time 
    shuffle children[v] randomly (each permutation with equal possibility) 
    // children[v] is vector of children cities of city v 
    for u in children[v]: 
    dfs(u) 

    As told before, Barney will start his journey in the root of the tree (equivalent to call dfs(1)).
    Now Barney needs to pack a backpack and so he wants to know more about his upcoming journey: for every city i, Barney wants to know the expected value of starting_time[i]. He’s a friend of Jon Snow and knows nothing, that’s why he asked for your help.

    下面是译文:

    Bob和Alice出去度蜜月,但Alice不慎走失,Bob在伤心过后,决定前去寻找Alice。
    他们度蜜月的地方是一棵树,共有N个节点,Bob会使用下列DFS算法对该树进行遍历。

    starting_time是一个容量为n的数组
    current_time = 0
    dfs(v):
    current_time = current_time + 1
    starting_time[v] = current_time
    将children[v]的顺序随机排列 (每个排列的概率相同)
    // children[v]v的直接儿子组成的数组
    for u in children[v]:
    dfs(u)

    1是这棵树的根,Bob会从1出发,即运行dfs(1),现在他想知道每个点starting_time的期望值。

    终于把这道题搞出来了... 汪汪大哭

    真的是一道很好的期望dp题目

    将到达每个节点$u$的期望时间戳记为$ans[u]$ 因为他是随机$dfs$所以他的兄弟节点会对他的期望时间戳产生贡献

    横向来看 只看该节点与他的兄弟节点 将其父亲的儿子个数记为$m$ 也就是包括他自己的兄弟节点的个数

    假设他在当前兄弟的$dfs$序中排名为$i$ 那么其余的每个兄弟节点排在他前面的概率是$frac{i - 1}{m - 1}$

    所以每个兄弟节点$bro$对他产生的贡献为$frac{i - 1}{m - 1}cdot size[bro]$ 

    那么总贡献为 $frac{i - 1}{m - 1}cdot sum_{bro eq  u}size[bro]$ 

    将$sum_{bro eq  u}size[bro]$ 记作$sum$ 易知$sum = size[fa] - size[u] - 1$ 减一是因为减去该子树的根节点

    显然 节点$u$排名为$i$的情况的概率为$frac{1}{m}$

    所以$ans[u] = frac{1}{m}cdot sum_{i = 1}^{m}frac{i - 1}{m - 1}cdot sum$

    化简得 $ans[u] = frac{1}{2}cdot sum$

    最后$ans[u] += ans[fa] + 1$ 加一是加上前面访问完了之后下一步走到$u$的步数

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e6 + 5;
    int size[N], sum[N], head[N], nex[2 * N], tov[2 * N], n, tot;
    double ans[N];
    
    void add(int u, int v) {
        
        tot ++;
        nex[tot] = head[u];
        tov[tot] = v;
        head[u] = tot;
    }
    
    void dfs(int u, int fa) {
        
        size[u] = 1;
        for(int i = head[u];i;i = nex[i]) {
            int v = tov[i];
            if(v == fa) continue;
            dfs(v, u);
            size[u] += size[v];
        }
        for(int i = head[u];i;i = nex[i]) {
            int v = tov[i];
            if(v == fa) continue;
            sum[v] = size[u] - size[v] - 1;
        }
    }
    
    void Add_Edge( ) {
        
        scanf("%d",& n);
        for(int i = 1;i < n;i ++) {
            int fa;
            scanf("%d",& fa);
            add(fa, i + 1); add(i + 1, fa);
        }
        dfs(1, 1);
    }
    
    void Dfs(int u, int fa) {
        
        for(int i = head[u];i;i = nex[i]) {
            int v = tov[i];
            if(v == fa) continue;
            ans[v] = ans[u] + 1 + 0.5 * sum[v];
            Dfs(v, u);
        }
    }
    
    int main( ) {
        
        Add_Edge( );
        ans[1] = 1; Dfs(1, 1);
        for(int i = 1;i <= n;i ++) printf("%.1lf ", ans[i]);
    }
  • 相关阅读:
    一个bug案例分析
    《需求工程》阅读随笔-1.做什么和怎么做
    连贯接口(fluent interface)的Java实现及应用。
    代码覆盖率检测工具大全
    腾讯的一个移动端测试小工具GT
    用复制mysql/data 文件夹 下面的数据库的形式来复制数据库出现的问题
    淘客API升级后的解决方案,怎么采集淘宝的商品数据
    方维团购系统,给供货商添加省市地址
    支付宝担保交易收款接口使用
    方维分享系统首页,插入新品,用来做优化
  • 原文地址:https://www.cnblogs.com/Rubenisveryhandsome/p/9752921.html
Copyright © 2011-2022 走看看