问题描述

跳蚤国正在大力发展旅游业,每个城市都被打造成了旅游景点。
  许多跳蚤想去其他城市旅游,但是由于跳得比较慢,它们的愿望难以实现。这时,小C听说有一种叫做火车的交通工具,在铁路上跑得很快,便抓住了商机,创立了一家铁路公司,向跳蚤国王请示在每两个城市之间都修建铁路。
  然而,由于小C不会扳道岔,火车到一个城市以后只能保证不原路返回,而会随机等概率地驶向与这个城市有铁路连接的另外一个城市。
  跳蚤国王向广大居民征求意见,结果跳蚤们不太满意,因为这样修建铁路以后有可能只游览了3个城市(含出发的城市)以后就回来了,它们希望能多游览几个城市。于是跳蚤国王要求小C提供一个方案,使得每只跳蚤坐上火车后能多游览几个城市才回来。 小C提供了一种方案给跳蚤国王。跳蚤国王想知道这个方案中每个城市的居民旅游的期望时间(设火车经过每段铁路的时间都为1),请你来帮跳蚤国王。
输入格式
  输入的第一行包含两个正整数n、m,其中n表示城市的数量,m表示方案中的铁路条数。
  接下来m行,每行包含两个正整数u、v,表示方案中城市u和城市v之间有一条铁路。
  保证方案中无重边无自环,每两个城市之间都能经过铁路直接或间接到达,且火车由任意一条铁路到任意一个城市以后一定有路可走。
输出格式
  输出n行,第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。数据有梯度。

解决过程

仔细一看,这根本就不是最短路问题嘛。
让我们简化一下问题
只求 i=1的 情形。

问题变成,对于城市1来说,出发回到原点的期望时间是多少?

首先,要明确几件事情

引理一

对于出发点城市1来说,出发到每个子节点的概率之和(出度)与父节点到本节点的概率之和(入度)相等,且为1。
这里的出度和入度,都是借用网络流概念。
很显然,城市1即是起点也是终点。
【蓝桥杯】观光铁路(SPFA算法运用于非最短路问题)
也就是说,乘客一定会回到原点,即使时间是

引理二 加权平均

对于概率p1,p2pn与相对应的值x1,x2xn
它们的平均期望应该是

x¯=i=1npixii=1npi

这个平均期望对应的概率是
p=i=1npi

对于某个节点k
【蓝桥杯】观光铁路(SPFA算法运用于非最短路问题)
到达k的平均期望就是x¯,到达k的概率就是p
(如果以父节点的时间计算的话k的平均期望就是x¯+i=1npi1i=1npi=x¯+1)

而这道题中有这么一个性质

性质:子节点不会影响父节点,父节点只会影响子节点。

这个性质可能看起来不怎么样。
让我们回想一下SPFA算法对Bellman - Ford算法的最大优化在哪?
对某个节点松弛操作后,只有这个节点的子节点受到了影响
对了
这就是SPFA的核心思想

于是我们可以得出求解城市1的了

步骤

  1. 建立两个数组,概率p[i],时间x[i],i为城市节点。显然p[1]=100%=1,x[1]=0
  2. 城市1入队,指针i指向城市1.
  3. 除了城市1,如果p[i]x[i]<1E9(109) 那么跳到步骤7。否则继续执行步骤4。
  4. 计算子节点的数量ni和平分给子节点的概率P=p[i]ni
  5. 对于所有在队列内的子节点k(如果城市1是子节点那么也算在队列内,虽然实际并不在内),计算并赋值加权平均
    x[k]=(x[i]+1)P+x[k]p[k]P+p[k]
    和概率
    p[k]=P+p[k]
  6. 将所有在队列外的子节点j入队(城市1除外)。对于每一个j,赋值p[j]=P,x[j]=x[i]+1
  7. 对于本身节点,赋值p[i]=0,x[i]=0,出队,指针i移向下一位。
  8. 直到队列为空。
解释

第3步.这是搜索的边界条件。可以证明,时间的增长速度比概率的衰减速度要慢的多,对最终结果的影响有限。当然,存在有更精确的边界条件。不是唯一的。
第7步.这是保证,在队列内的概率总和不会大于100%。也就是说,回到城市1的概率不会大于100%。

于是我们就获得了单源的算法。
所以,对于所有的i,都进行一次上面的类SPFA操作,就可以求得答案了。
由上面的边界条件可以看到,在最理想的情况下,一个点要经历估算至少log210930次入队才会排除
那么算法时间O(kE)O(V)=O(kV2)(k为节点平均入队次数,30,E为边数,V为节点数。由无重边无自环,所以E=V)
还算是理想的效率.

相关文章: