费用流与对偶图

本文介绍了费用流的概念,重点讲解了最小费用最大流的求解思路,包括通过寻找最短路和更新边的流量来确保最大流和最小费用的平衡。同时,讨论了对偶图在解决网格图最大流TLE问题中的应用,证明了对偶图最短路与平面图最大流的关系,并给出了建立对偶图的示例。最后,探讨了在实现过程中需要注意的细节,如避免死循环和优化SPFA算法。

费用流

那是啥?
常见费用流为最小费用最大流。第一关键字为最大流,次大关键字为最小费用。就是说 每条边有他自己的花费,你尽可能的选择便宜的边流。
怎么做呢?
1.找一条单位花费综合最少的路(最短路)
2.找到其中流量最小的边f
3.流完这些f的量 相应更新数值
4.若仍s-t联通 重复上述
正确性证明:与dinic相似,最大流得到了保证,另外,每次的花费保证当前是最小的,可以通过脑补证明该贪心正确。
代码暂时不呈现(主要是因为出了玄学错误 linux和windows运行结果不同)

对偶图

这个东西主要是解决网格图跑最大流的TLE问题的,此处有个证明:对偶图最短路==平面图最大流
证明如下:对偶图的路径=平面图的割 则对偶图的最短路就是平面图的最小割 那么应用最大流最小割定理 得证。
Q:那么对偶图怎么建立?
A:YY!
因为对偶图在OI的应用主要是网格图,所以比较规则,自行YY即可,看一道例题:
http://www.lydsy.com/JudgeOnline/problem.php?id=1001
著名的BZOJ1001
那么我们可以这个样子YY一下,网格图的对偶图必然是在框内的,那么我们框内的数字一定要有序,然后我们可以YY这样一个情况
这里写图片描述
代码是这样的

emm=(m-1)*(n-1);s=0,t=(m-1)*(n-1)*2+1;
    so(i,1,n*(m-1),1) 
    {
        scanf("%d",&x);
        //u=min(t,i);//v=max(s,i-m+1);
        if(i>emm) u=t;
        else u=i;
        if(i-m+1>0) v=i-m+1+emm;
        else v=0;
        link(u,v,x),link(v,u,x);
    }
    so(i,1,n-1,1) so(j,0,m-1,1)
    {
        scanf("%d",&x);
        if(!j) u=t;
        else u=(i-1)*(m-1)+j; 
        if(j==m-1) v=s;
        else v=(i-1)*(m-1)+j+1+emm;
        link(u,v,x);link(v,u,x);
    }
    so(i,1,emm,1)
    {
        scanf("%d",&x);
        link(i,i+emm,x);link(i+emm,i,x);
    }

很美丽,那么有个问题 s为啥不用0?如果您是vector选手,没关系,但如果您使用邻接表!当h[0]=0的时候便会死循!一定要切记。
然后我们开开心心写个SPFA就好啦~
然后:

这里写图片描述
为啥呢?SPFA在如此稠密的图中 复杂度退化为 O(n2) O ( n 2 ) (因为边数比网格图还多!!)
唉,谁让我校不擅长堆优化dij呢?那我写个双端队列优化试试?
这里写图片描述
MLE??这是个啥。。。我写挂了?
所以啊——学dij学dij学dij!

### 最小费用问题对偶线性规划的关系 最小费用问题是网络理论中的一个重要分支,旨在找到满足给定量需求的同时使总运输成本最低的方案。该类问题可以通过构建相应的线性规划模型来表示,并利用其对偶问题进行求解。 #### 构建线性规划模型 在网络图 \( G=(V,E) \) 中定义每条边上的单位传输代价 \( c_{ij} \),以及容量限制 \( u_{ij} \)[^1]。设 \( f_{ij} \) 表示沿弧 (i, j) 的实际量,则可建立如下标准形式的最大最小费用问题: \[ \begin{aligned} & \text { minimize } & C(f)=\sum_{(i, j) \in E} c_{ij}f_{ij}\\ & \text { subject to } \\ && \sum_{j:(s,j)\in E} f_{sj}-\sum_{t:(t,s)\in E} f_{ts}=d_s,\quad s\in V\\ && 0 \leqslant f_{ij}\leqslant u_{ij},\quad(i,j)\in E \end{aligned} \] 其中 \( d_s \) 是节点 s 处的需求量或供给量,在源点处为正数而在汇点处为负数,其他中间结点则保持平衡状态。 #### 转换成对偶问题 为了转换成对偶问题,考虑引入拉格朗日乘子 λ 和 μ 来松弛上述约束条件。对于每一个顶点 i ,都有一个对应的变量 \( y_i \),代表到达此位置的成本调整因子;而对于每一条边 e 上设置两个额外参数 w_e 和 z_e 分别对应上下界限制的影响程度[^3]。因此得到以下对偶表达式: \[ \begin{array}{lll} & \max & b^{T}y+\sum_{e}(u_{e}z_{e})-\sum_{e}(lz_{e}) \\ & \mathrm{s.t.} & A^{T}y+c-w+z=0 \\ & & l \leq x \leq u \\ & & w,z \geq 0 . \end{array} \] 这里矩阵A包含了所有路径上各边权重的信息,向量c记录了原始目标函数系数,而b则是关于供应/消耗情况的数据集合。 通过这样的变换过程可以看出,原问题中寻找最优解的任务被转化为在一个扩展空间里寻求能够使得新构造的目标达到最大的一组可行解集的问题。这种方法不仅简化了计算难度,而且有助于理解两者间内在联系的本质特征。 ```python from scipy.optimize import linprog # 定义最小费用问题的相关数据结构 cost_matrix = [[...]] # 成本矩阵 capacity_matrix = [[...]] # 容量矩阵 demand_vector = [...] # 需求向量 # 将最大最小费问题转置为其对偶形式并调用linprog求解器 res_dual = linprog(-demand_vector, bounds=[(None, None)] * len(demand_vector), method='revised simplex') print(res_dual) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值