树上游走(寒假集训结束试题)

博客介绍了在一棵树上进行随机行走的问题,其中起点s到终点t的行走遵循特定规则。行走期望经过的点数需要计算,每个点被多次经过只计算一次。问题的关键在于理解当朝着t走时不会返回,否则会遍历整个子树。解决方案涉及到对路径上和非路径上点的期望概率计算,可以实现为O(nlogn+m)的时间复杂度。文章提供了样例输入和输出,并提到考场上的思考过程和最终简化问题的方法。
摘要由CSDN通过智能技术生成

【题目描述】
有一棵n个点的树。
有m次询问,每次给定起点s和终点t,会从s走到t。由于眼神不好,它会按如下方式走路:
(1)初始时在s,如果到达t就立刻停止;
(2)如果相邻点中存在离s更远且没走过的点,那么等概率随机一个满足条件的点走过去;
(3)否则,往s所在方向走一步。
你需要求出期望经过多少个点(包括s和t)。一个点被多次经过只计算一次。
【输入数据】
第一行两个整数n,m,接下来n-1行每行两个整数u,v表示一条边,接下来m行每行两个整数s,t表示一组询问。
【输出数据】
每组询问输出一行一个实数表示答案,保留一位小数。
【样例输入】
3 3
1 2
2 3
1 2
1 3
2 3
【样例输出】
2.0
3.0
2.5
【数据范围】
对于10%的数据,n,m<=7。
对于30%的数据,n,m<=100。
对于60%的数据,n<=5000。
对于100%的数据,1<=n,m<=500000,s!=t。

题解:首先不难发现,如果某一步是朝着t走的,那么一定不会走回来了;否则,一定会把整棵子树走完再回到当前点。走到一个s到t路径上的点时,会随机选择一个儿子走下去,这等价于随机一个儿子们的排列,然后按这个顺序走。那么s到t的路径上所有点显然一定会走到,以s为根时t子树中的点显然走不到,而其它点都有1/2的概率会走到。时间复杂度O(nlogn+m)。
考场时想到了除了在路径上的点,其他的点连接的点都有1/2的概率走到。但是,想到的都是些线段树修改什么的感觉有点假很复杂,肯定又是一百多行的代码,没有想下去。

其实就是把在路径上的点赋值为1,余下的连接的点赋值为1/2。分在同一条链上的情况,和在两颗子树的情况,重点在于求那些点是不需要走的。详见代码。

#include<bits/stdc++.h>
 using namespace std;
const int MAXN=10000000; 
int n,m;
vector< int > a[MAXN];
int p[MAXN][25],deep[MAXN],size[MAXN],f;
double ans[MAXN];
void dfs(int x,int dep)
{
    
    for(int i=1;i<=22;i++)
     p[x][</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值