费用流与对偶图

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

费用流

那是啥?
常见费用流为最小费用最大流。第一关键字为最大流,次大关键字为最小费用。就是说 每条边有他自己的花费,你尽可能的选择便宜的边流。
怎么做呢?
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!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值