这里以第一篇题解为例补充说明。
第一篇题解代码里求的那个东西,也就是:
if(dis[v]==dis[u]+e[i].w) cnt[v]++;
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
cnt[v]=1;
q.push(make_pair(dis[v],v));
}
实际上 cnt[u] 并不是 1 到 u 的最短路径数量,而是满足 1⇝v→u 为一条最短路径的点 v 的数量。上面这个路径 1⇝v 通过多条边(可以是一条甚至是零条)的路径到达,v→u 通过一条边直接到达。
如果想要统计 1⇝u 的最短路径数量,正确的写法是这样的。
if(dis[v]==dis[u]+e[i].w) cnt[v]+=cnt[u];
if(dis[v]>dis[u]+e[i].w){
dis[v]=dis[u]+e[i].w;
cnt[v]=cnt[u];
q.push(make_pair(dis[v],v));
}
事实上,最短路径数量和“点 v 数量”在本题中判断都无问题。
考虑最短路径数量 >1 的情况,如果有一条最短路径经过特殊边,那么第二条最短路径肯定是不经过特殊边的,因为这题里边权都是正的,经过一条特殊边之后权值就已经到了最短路,不能再走多余的路了。
而满足 1⇝v→u 为一条最短路径的点 v 的数量如果 >1,意味着合法的点 v 除了点 1 以外必然有一个其它点,经过这个点的那条最短路径一定不经过特殊边。
但是,最短路径数量有一个问题:上界可以很大。即使不允许重边,也能构造出这么一个东西:

1⇝4 有两条最短路径,4⇝7 有两条最短路径,7⇝10 有两条最短路径,10⇝13 有两条最短路径,13⇝16 有两条最短路径,所以 1⇝16 的最短路径数量是 25=32。
这个增长速度是指数爆炸的,只要我们再接着接下去,大概达到的最短路径数量上界是 2n/3。如果想要直接统计出这样的数量,高精度是无可避免的。
所以本题直接统计最短路径数量再判断是不太合理的。一种处理方式是采用上面的“点 v 数量”策略,还有一种处理方式是,我们并不关心最短路径数量的具体值,只关心最短路径数量是否 >2,因此等到最短路径数量 =2 之后不让它再加下去就可以了。