问题描述
跳蚤国正在大力发展旅游业,每个城市都被打造成了旅游景点。
许多跳蚤想去其他城市旅游,但是由于跳得比较慢,它们的愿望难以实现。这时,小C听说有一种叫做火车的交通工具,在铁路上跑得很快,便抓住了商机,创立了一家铁路公司,向跳蚤国王请示在每两个城市之间都修建铁路。
然而,由于小C不会扳道岔,火车到一个城市以后只能保证不原路返回,而会随机等概率地驶向与这个城市有铁路连接的另外一个城市。
跳蚤国王向广大居民征求意见,结果跳蚤们不太满意,因为这样修建铁路以后有可能只游览了3个城市(含出发的城市)以后就回来了,它们希望能多游览几个城市。于是跳蚤国王要求小C提供一个方案,使得每只跳蚤坐上火车后能多游览几个城市才回来。 小C提供了一种方案给跳蚤国王。跳蚤国王想知道这个方案中每个城市的居民旅游的期望时间(设火车经过每段铁路的时间都为1),请你来帮跳蚤国王。
输入格式
输入的第一行包含两个正整数n、m,其中n表示城市的数量,m表示方案中的铁路条数。
接下来m行,每行包含两个正整数u、v,表示方案中城市u和城市v之间有一条铁路。
保证方案中无重边无自环,每两个城市之间都能经过铁路直接或间接到达,且火车由任意一条铁路到任意一个城市以后一定有路可走。
输出格式
输出n行,第i行包含一个实数tBit_{B_i}tBi,表示方案B中城市i的居民旅游的期望时间。你应当输出足够多的小数位数,以保证输出的值和真实值之间的绝对或相对误差不超过1e-9。
样例输入
4 5
1 2
2 3
3 4
4 1
1 3
样例输出
3.333333333333
5.000000000000
3.333333333333
5.000000000000
数据规模和约定
对于10%的测试点,n <= 10;
对于20%的测试点,n <= 12;
对于50%的测试点,n <= 16;
对于70%的测试点,n <= 19;
对于100%的测试点,4 <= k <= n <= 21,1 <= u, v <= n。数据有梯度。
解决过程
20241020更新
用一个更直观的说法来分析这个问题
让我们先考虑某一个节点的情况
假设只考虑出发点s,和其他中间节点,会得到如上的关系图,其中aaa表示回到s的概率
我们可以利用马尔可夫链来解释整个流程
设置某个状态下各节点待出发的s城居民为[sm]\begin{bmatrix}s\\m\end{bmatrix}[sm],初始状态[10]\begin{bmatrix}1\\0\end{bmatrix}[10]。
则可以用状态转移方程来描述经过一个单位时间后的状态[s′m′]\begin{bmatrix}s'\\m'\end{bmatrix}[s′m′]:
[s′m′]=[0011−a][sm]
\begin{bmatrix}s'\\m'\end{bmatrix}=\begin{bmatrix}0&0\\1&1-a\end{bmatrix}\begin{bmatrix}s\\m\end{bmatrix}
[s′m′]=[0101−a][sm]
在状态转移矩阵中第一行参数全为0,是因为题目说回到s的人就不会再出发。
第二行第一列的参数为1,是因为此处只有一个节点,出发到此节点的概率是100%。如果有多个节点,根据题意应该是平分概率。
那么经过绝对够长的一个时间以后,最终状态[s∗m∗]\begin{bmatrix}s^*\\m^*\end{bmatrix}[s∗m∗]为
[s∗m∗]=limn→∞[0011−a]n[sm]=limn→∞[00(1−a)n−1(1−a)n][sm]
\begin{bmatrix}s^*\\m^*\end{bmatrix}=\lim_{n\to \infty}\begin{bmatrix}0&0\\1&1-a\end{bmatrix}^n\begin{bmatrix}s\\m\end{bmatrix}=\lim_{n\to \infty}\begin{bmatrix}0&0\\(1-a)^{n-1}&(1-a)^n\end{bmatrix}\begin{bmatrix}s\\m\end{bmatrix}
[s∗m∗]=n→∞lim[0101−a]n[sm]=n→∞lim[0(1−a)n−10(1−a)n][sm]
当a>0a>0a>0时,[s∗m∗]=[00]\begin{bmatrix}s^*\\m^*\end{bmatrix}=\begin{bmatrix}0\\0\end{bmatrix}[s∗m∗]=[00]
也就是说,当a>0a>0a>0时乘客一定会回到原点,即使时间是∞\infty∞,即使有概率上的自环。
之前的原文
仔细一看,这根本就不是最短路问题嘛。
让我们简化一下问题
只求 i=1i=1i=1的 情形。问题变成,对于城市111来说,出发回到原点的期望时间是多少?
首先,要明确几件事情
引理一
对于出发点城市111来说,出发到每个子节点的概率之和(出度)与父节点到本节点的概率之和(入度)相等,且为1。
这里的出度和入度,都是借用网络流概念。
很显然,城市1即是起点也是终点。
也就是说,乘客一定会回到原点,即使时间是∞\infty∞
引理二 加权平均
假设现在仅有n个城市与m相连,从S市到达它们分别走了x1,x2……xnx_1,x_2……x_nx1,x2……xn的时间,而现在,从它们出发,有p1,p2……pnp_1,p_2……p_np1,p2……pn的概率会到达中间节点m。
那么问题就是,这些城市到达m市的平均时间是多少?
对于概率p1,p2……pnp_1,p_2……p_np1,p2……pn与相对应的值x1,x2……xnx_1,x_2……x_nx1,x2……xn
它们的平均期望应该是
xˉm=∑i=1npi∗(xi+1)∑i=1npi\bar x_m ={ \sum_{i=1}^{n} p_i*(x_ i+1) \over \sum_{i=1}^{n} p_i}xˉm=∑i=1npi∑i=1npi∗(xi+1)
除了平均时间以外,我们还想知道到达m市的概率,这个概率是p=∑i=1npi p=\sum_{i=1}^{n} p_ip=i=1∑npi
现在,如果这时发现还有一个城市xθx_\thetaxθ与m相连,此时,在数学上,我们可以快速得出新的期望和概率
xˉm′=xˉm∗p+(xθ+1)∗pθp+pθ,p′=p+pθ
\bar x_m '={\bar x_m*p+(x_\theta+1)*p_\theta \over p+p_\theta},\quad p'=p+p_\theta
xˉm′=p+pθxˉm∗p+(xθ+1)∗pθ,p′=p+pθ
我们可以发现,对于每个节点,都可以进行类似的操作。如果把x1,x2……xnx_1,x_2……x_nx1,x2……xn看作是m的父节点,那么这个过程其实与最短路是很像的,区别在于最短路是在所有父节点中选择最短的节点,而本题是在所有父节点中取概率加权平均。
而这道题中有这么一个性质
性质:子节点不会影响父节点,父节点只会影响子节点。
这个性质可能看起来不怎么样。
让我们回想一下SPFA算法对Bellman - Ford算法的最大优化在哪?
对某个节点松弛操作后,只有这个节点的子节点受到了影响。
对了
这就是SPFA的核心思想
于是我们可以得出求解一个城市的单源算法了
以1号城市为例
步骤
- 建立两个数组,概率p[i]p[i]p[i],时间x[i]x[i]x[i],iii为城市节点。显然p[1]=100%=1,x[1]=0p[1]=100\%=1,x[1]=0p[1]=100%=1,x[1]=0
- 建立一个待处理队列,城市1入队,指针iii指向城市1.
- 除了城市1以外,如果p[i]∗x[i]<1E−9p[i]*x[i]<1E^{-9}p[i]∗x[i]<1E−9 (题目要求的精度) 那么跳到步骤7。否则继续执行步骤4。
- 对于城市iii,计算子节点的数量nin_ini和平分给子节点的概率pchild=p[i]nip^\text{child}=\dfrac{p[i]}{n_i}pchild=nip[i]
- 对于所有在队列内的子节点kkk(如果出发点城市1是子节点那么也算在队列内,但不赋值),计算并赋值其加权平均时间x[k]=(x[i]+1)∗pchild+x[k]∗p[k]pchild+p[k]x[k]=\dfrac{(x[i]+1)*p^\text{child}+x[k]*p[k]}{p^\text{child}+p[k]}x[k]=pchild+p[k](x[i]+1)∗pchild+x[k]∗p[k]和概率p[k]=pchild+p[k]p[k]=p^\text{child}+p[k]p[k]=pchild+p[k]
- 将所有在队列外的子节点jjj入队(城市1除外)。对于每一个jjj,赋值p[j]=pchild,x[j]=x[i]+1p[j]=p^\text{child},x[j]=x[i]+1p[j]=pchild,x[j]=x[i]+1。
- 对于本身节点,赋值p[i]=0,x[i]=0p[i]=0,x[i]=0p[i]=0,x[i]=0,出队,指针iii移向下一位。
- 直到队列为空。
解释
第3步.这是搜索的边界条件。当某个城市的到达概率微乎其微,当然是要忽略它了。可以证明,时间的增长速度比概率的衰减速度要慢的多,对最终结果的影响有限。当然,存在有更精确的边界条件。不是唯一的。
第7步.这是保证,在队列内的概率总和不会大于100%。也就是说,回到城市1的概率不会大于100%。
这个算法会让节点多次入队,因为有些居民可能多次兜圈子,但是每次访问节点对应的居民花费时间是不同的。
于是我们就获得了单源的算法。
所以,对于所有的iii,都进行一次上面的类SPFA操作,就可以求得答案了。
由上面的边界条件可以看到,在最理想的情况下,一个点要经历估算至少log2109≈30\log_2 10^{ 9} \approx 30log2109≈30次入队才会排除
那么算法时间O(kE)∗O(V)=O(kV2)O(kE)*O(V)=O(kV^2)O(kE)∗O(V)=O(kV2)(k为节点平均入队次数,≥30\ge 30≥30,E为边数,V为节点数。由无重边无自环,所以E=V)
还算是理想的效率.