费用流处理负圈的方法
以最小费用最大流为例,我们可以通过退流来消除费用为负数的边。
具体过程:
不妨设有一条从\(u\)到\(v\)的容量为\(c\)费用为\(d\)的边(\(d<0\))。
先强制满流,把答案加上\(c\times{d}\)。
之后,从\(u\)到\(T\),\(S\)到\(v\)各连一条容量为\(c\),费用为0的边,用来调整流量。这两条边要使用手段强制满流。
最后,连一条从\(v\)到\(u\)的容量为\(c\)费用为\(-d\)的边,用于退流。
这样就没有负环了。
也有解决负环的算法:
此写法过慢,待修改
正常,我们的最小费用流的费用都应该是正数。
但是,有时,边权会出现负数,进而可能出现负圈。
这时,我们可以这样处理:
在每次增广时,先在整张图中找负圈,若能找到,则沿着负圈增广。
否则,再找增广路进行增广。
找负圈使用dfs的spfa会更好写,更快。
可以优化:
- 每个点只搜索一次(见注释)。
- 如果搜不到负环了,就不需要再考虑负环了。
代码:
bool dfs(int u)
{
bk[u]=true;
for(int i=fr[u];i!=-1;i=ne[i])
{
if(w[i]>0&&jl[u]+fy[i]