最短路是图论中非常常见的一种算法,一般来所,很多考试的第三题都会多多少少和最短路算法沾点边,而许多oier常用的是SPFA算法,也就是队列优化后的Bellman-Ford算法,但是实际上,这种算法具有非常大的不稳定性,也就是说,只要出题人愿意,他可以分分钟卡死你。所以一般考试时,只要数据没有到千万级别,一般我们会采用dijkstra堆优化的方式来写最短路。
所谓dijkstra,就是红白点的一种最短路算法,每次找到所有点中dis值最小的点,以其为起始点来更新其他点的dis值。一般来说,这种算法的实际复杂度为$n^2$,常数上不大(确信),而我们发现,这里有一部是需要找到所有点中dis值的最小值,我们就可以使用对的方式来优化,可以将复杂度降至(nlogn)(实际上由于点数的膨胀,复杂度可能会超过$2nlogn$),那么在考场上,手写堆是十分耗时的,而且万一写错就彻底爆炸了,所有我们可以采用stl中的一种类堆结构:单调队列(priority_queue)来维护。
算法原理很简单,就是用单调队列来维护每次找寻的最小值,但是实际操作中却长长有一点小问题:
1.默认的stl是从大到小排列的,所以我们要重载小于号为大于号才能让其变成小根堆。
2.一般来说,这个算法每个点的dis值是在不断变化的,所以我们需要将每个变化的值,连同其坐标一起丢入单调队列之中,每次去除队首元素时,首先判断其是否被用过。
下面附代码:
1 | #include<bits/stdc++.h> |