寻找【NOIP2016提高A组模拟7.17】

28 篇文章 0 订阅
9 篇文章 0 订阅

题目:

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的期望值。

样例输入:
第一行一个数N,表示节点数
第二行N-1个数,第i个数表示节点i+1的父节点(保证parent[i] < i)
7
1 2 1 1 4 4

样例输出:
1.0 4.0 5.0 3.5 4.5 5.0 5.0

数据范围:
对于30%的数据,N<=1000
对于100%的数据,N<=100000


剖解题目:

给一颗有根树以及树上点的关系,问所有遍历后的序列中,每个节点出现的位置的期望值。


思路:

期望值的题目诶,一般就是努力推推公式之类的把。


解法:

反正我对概率期望一向都不会,看来回去得恶补……
这道题,可以通过组合数和一些阶乘的方法推出公式。
公式:当前节点的期望值=父亲的期望值+(Size父亲-Size当且节点-1)/2+1。(size表示这棵子树的大小(也就是这棵子树的节点数))。
然而,我现在也不会证.


代码:

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for(int i=a;i<=b;i++)

using namespace std;

const int maxn=1e5+3;
int a[maxn],f[maxn][150],n,dad[maxn],num[maxn];
double ans[maxn];
bool bz[maxn];

void dfs(int x)
{
    if (!f[x][0]) num[x]=1;
    else {
        fo(i,1,f[x][0]){
            dfs(f[x][i]);
            num[x]+=num[f[x][i]];
        }
        num[x]+=1;
    }
}
int main()
{
    //freopen("T1.in","r",stdin);
    scanf("%d",&n);
    dad[1]=1;
    fo(i,1,n) {
        scanf("%d",&a[i]);
        f[a[i]][++f[a[i]][0]]=i+1;
        dad[i+1]=a[i];
    } 
    dfs(1);
    int h=0,t=1,d[maxn];
    memset(d,0,sizeof(d));
    d[1]=1; ans[1]=1.0;
    while (h!=t) {
        ++h;
        int u=d[h];
        if (u!=1) ans[u]=ans[dad[u]]+((double)(num[dad[u]]-num[u]-1))/2+1;
        fo(i,1,f[u][0]) d[++t]=f[u][i];
    }
    fo(i,1,n) printf("%.1lf ",ans[i]);
//  fclose(stdin);
}

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值