迷宫
题意:给n个点和m条无向边,求1到n的次短路。
方法一
对于次短路,之前我是没学过的,模拟赛遇到此题,想了半天怎么实现,想出了自己的独特方法:
对于每个点我们都保存起点到它的最短路长度和次短路长度
1 | struct node{ |
像SPFA一样,一旦能更新就入队,但难点在于fir
和sec
的互相转移。
- 首先考虑
u
的最短路能够更新to
的最短路时,即:a[to].fir>a[u].fir+val
(val
为边权),此时让to
的次短路等于to
的最短路,to
的最短路等于a[u].fir+val
- 再考虑
to
的次短路和u
的次短路的更新关系,很容易想到当a[to].sec>a[u].sec+val
时直接更新是没有问题的。 - 最后时
u
的最短路介于to
的最短路和次短路之间,这里有个前提,必须要在没有操作第一步时才能操作。转移就是:a[to].sec=a[u].fir+val;
以上操作一旦能执行to
就要入队,因为它的值被更新了,要用它去更新后面的点。
方法二
看网上的方法,是用最短路算法预处理出每个点到起点和终点的最短路,然后枚举每条边,比较出第二短的路。
实测得方法一跑地比方法二快
代码(方法一)
1 |
|
你看其实实现并不是很难,除了fir
与sec
的转化有点思维含量(毕竟考试时只能想出这样无脑的方法,但我跑的就是比std快)