link
关于 Dijkstra+EK 实现的费用流。
考虑将算法中的 spfa 替换成 Dijsktra,但由于有负边,考虑乱搞势能函数将边权全部弄成正数。
一个很显然的错解是 \(\forall e_i,e_i=e_i+\min\{e\}\),因为我们不知道最短路径上有几条路。
定义势能函数 \(del_i\)。把 \(x\) 到 \(y\) 的边权从 \(e_{x,y}\) 换成 \(del_u-del_v+e_{u,v}\),并且能保证对于任意一条边,\(del_u-del_v \geqslant -e_{u,v}\),那么图中就没有负边了,我们就可以继续使用 Dijkstra。
而且我们考虑从起点 \(S\) 到 \(T\) 的一条路径,如果每条边都这样处理,实际上路径上除了 \(S\) 到 \(T\) 之外的其他点的势函数都被抵消了,最后得到的路径权值是原始路径长度加上 \(del_S-del_T\),这样我们求出最短路之后,只需要加上 \(del_T\) 减去 \(del_S\)。一般来说 \(del_T=0\)。
这里提供一种构造方法,我们令 上一次的最短路径 \(dp_i\) 为这次的 \(del_i\)。
考虑两种情况:
- 上次增广此条边没变,根据最短路的性质:\(dp_y\leqslant dp_x+e_{x,y}\),符合上述条件。
- 上次增广后此条边被加,那么此条边的反边一定在最短路径上,那么 \(dp_y=dp_x+e_{x,y}\),显然满足 \(dp_y-dp_x\geqslant -(-e_{x,y})\)(此时取等)。
故上述构造方法合理。如果刚开始有负边,我们要先跑一遍 spfa 求出最短路径,如果没有,直接令 \(del_i=0\) 亦可。
回归本题。
板子。考虑搞成二分图,两边都连(即 \(x\) 连 \(y+n\),\(y\) 连 \(x+n\)),贪心地来想,一组最优的匹配肯定是两条边都取,于是连边跑完后 \(ans\) 除以 \(2\) 即可。注意求最大边权取负。
#include
#include
#include
#include
#include
#include
#include