小结:最短路
概要:
最短路是个神奇的东西,通过三角不等式,我们可以拓展出很多最短路的延伸。而求最短路的算法一般我用三种,dijkstra、spfa、floyd,第一个用于点少边多的,第一个用于点多边少的,第三个是多源最短路。
应用:
差分约束系统、一般约束条件、最短路等。
技巧及注意:
差分约束:根据三角不等式d(v)<=d(u)+w(u, v),我们通过移项,还可以得到d(v)+w(u, v)<=d(u),而这样就足以解决一些不等式约束集了,即差分约束(在一些情况下,可以考虑最长路的三角不等式)。例如
- 【BZOJ】2330: [SCOI2011]糖果(差分约束+spfa),维护每个点的总的信息。
- 例如sum[i]表示对i这个点的进出的总量,然后有约束使得能够构造出差分约束一样的网络求出sum,例题在白书上有。
障碍限制:和bfs一样有个技巧,在求有障碍的约束时,即当出现这些起点到终点最多能越过k个障碍的图时,可以逆着想,我们想这个点到终点需要越过的最少障碍数,然后用k来判断是否合法即可,例如:
k短路:在A*的小结中已讲
次短路:对于次短路,我们可以没那么麻烦用A*做,可以在最短路的基础上再维护一个数组就行了。转移状态时注意下即可。例题:
特殊技巧:这种靠智商了,看你能否建成最短路模型。其实多想想就行了。例如:
分数规划:这种属于01分数规划中的一种,就是求“每一个物品只有选或者不选两种方案,求一个选择方案使得 R=sigma(a[i]*x[i])/sigma(b[i]*x[i])取得最值,即所有选择物品的总收益/总代价的值最大或是最小。”,那么我们移项后设F(L)=sigma(a[i]*x[i])-L*sigma(b[i]*x[i]),(x[i]表示i这个点是否选)而这里的L和我们的R关系密切,我们只需要找出最大的L就能找出R。对于每个L,如果F(L)>0时说明还能找到一个更优解(或者一些题目中是F(L)<0),且F(L)是具有单调性的,因此我们可以二分L,然后如果F(L)>0,那么移动上界,否则移动下界(视题目情况而定)。例题:
判负环:这种最好用dfs版本的spfa做,要不然会tle,例题:
spfa优化:在进队列的时候,如果d[v]<d[q[front]]时,加入到前边。这个优化的英文简称叫啥来着。例题:
对偶图:用于求平面图的最小割,根据欧拉定理e-v+2=f易得出二维平面的个数(显然少了很多),然后对应的割连边,例题:
乘积最短路:一些题目中三角不等式并不是简单的加法,而是形如d[v]<=d[u]+d[u]*w[u,v]这一类的问题,因为log(d[v])<=log(d[u]+d[u]*w[u,v])化简可得log(d[v])<=log(d[u])+log(1+w[u,v]),那么问题转换为加法(这只能用作判定,似乎不能打出答案?我觉得pow(m, d[v])可以打出(m是底)?,例题:
层次图: