原始对偶算法

原始对偶算法

我们是只会背结论的不求甚解的好家伙

是一种费用流算法,其本质目的是将 spfa 优化为 dijkstra,可以解决没有负环的最小费用流问题。

下面全部假定为最小费用流。

流程:

  1. 预跑一次 spfa,设得到的最短路数组为 \(h\)
  2. 跑 dijkstra,将 \(u\to v\) 边权视作 \(cost(u,v)+h_u-h_v\),得到 \(dis\) 数组并记录增广路。
  3. 若无法到达 \(t\),退出,否则增广,并令 \(h'\leftarrow h+dis\)

即可,可以配合 zkw 费用流使用。

特殊线性规划转费用流

解决如下线性规划问题:

\[\min \sum b_ux_u+\sum cap(u,v)·\max(x_v-x_u-cost(u,v),0) \]

这本质是一个最小费用可行流问题。

为了避免关于 \(b\) 是否全为 \(0\) 的讨论,我们提出一种最通用的方法。

  1. 初始设 \(d_u=b_u\)

  2. 遍历所有负权\((u,v,cap(u,v),cost(u,v))\)

    \(d'_v\leftarrow d_v+cap(u,v),d'_u\leftarrow d_u-cap(u,v)\)强制负权边满流

接着建图:

  1. \(b_x>0\),建立 \((S,x,b_x,0)\),否则建立 \((x,T,-b_x,0)\)
  2. \((u,v)\)
    • \(cost(u,v)>0\),建立 \((u,v,cap(u,v),cost(u,v))\)
    • \(cost(u,v)<0\),建立 \((v,u,cap(u,v),-cost(u,v))\)

跑最小费用最大流即可。

看一下 max_flow 是否等于 \(\sum d_i[d_i>0]\),不等于则无解。

如何输出方案?

根据上面的算法,考察原图中每条边的实际流量 \(f\)

忽略 \(S,T\)

  1. \(f(u,v)<cap(u,v)\),建边 \((u,v,cost)\)
  2. \(f(u,v)>0\),建边 \((v,u,-cost)\)

建立虚点 \(V\),对 \(1\sim n\) 全部连边权为 \(0\) 的有向边。

用 SPFA 求最短路,\(x_u=dis_u\)

由于这是残量网络,一定不会存在负环。

posted @ 2026-04-05 16:17  spdarkle  阅读(20)  评论(0)    收藏  举报