关于最大费用最大流的一类问题 【小谈】


引子:给你一个N*M的矩阵,对应N*M个点,且每个点都有一定的点权。当第一次到达某个位置时,我们可以获得该位置的点权且只能获取这一次。现在让你从左上角出发,每次只能向下或者向右走~~~。 


当然是有限制的走

问题一:每个点只能走一次(除了起点和终点可以走多次),问你从左上角到右下角走两次所获取的最大权值和。

问题二:每个点无限走,问你从左上角到右下角走K次获取的最大权值和。


声明下,我要说的是建图,而不是怎么写代码。

这两种问题想了好久,姑且分享一下我的见解。错误的地方欢迎指正!!!O(∩_∩)O~~





我们默认把一个点 可以拆为 左点 和 右点(网络流解决问题很常用的手段,这里不细说)。

明确一下————当选择A点的左点或者右点时,都说明你选择了走A这个点。


情况一:每个点只能走一次(除了起点和终点可以走多次),问你走2次获取的最大权值和。


1,对可达边<u, v>的处理,注意是有向边

我们会考虑四种情况,题目要求————每个点只能走一次。所以我们如果选择走一个点就必须要获取它的点权,只有这样才能得到最大权值和。

如图


首先明确我们在左点时,只有一种选择————就是到达右点,只有这样才能保证选择一个点必须要获取该点的点权。

这样的话只有选择U右到V左,才能保证获取两个点的点权。


(1)u的左点连v的左点,说明不获取u的点权而获取v的点权,不符合。

(2)u的左点连v的右点,说明既不获取u的点权也不获取v的点权,不符合。

(3)u的右点连v的左点,说明既获取u的点权又获取v的点权,符合。

(4)u的右点连v的右点,说明获取u的点权而不获取v的点权,不符合。

因此,我们只能建(3)这一条边。边的容量为1或者其他值,因为前一条边已经限制了流量最大为1,所以只要容量大于或等于1就行了。

获取点权这一点我说的可能不是很合适,建议自己模拟一下,好好思考。当然若有严重的bug,欢迎指正

2,拆点

我们要保证超级源点到起点的2个流量能够传进来(因为我们要走两次,所以超级源点到起点的流量为2),并且终点到超级汇点的流量尽可能的传出去,这样才能最大化获得的权值和。

所以我们在拆点的时候,对起点和终点的处理是————建立容量为2的边,对其它点的处理————建立容量为1的边(访问后不能再访问)。 

因为若起点和终点拆成容量为1的边,那我们在起点的时候就只有一个选择:向上走或者向下走,在终点时只能选择是由上面的点传到终点还是由左边的点传入终点,这样的话就相当于求走一次的最大权值和,显然这样建图是不对的。


对于该问题的解决方案:建立超级源点source,超级汇点sink。

1,source向起点左点建边,容量为2,费用为0;

2,拆点,起点、终点拆成容量为2的边,其他点拆成容量为1的边,费用为点权;

3,<u, v>可达边,则u的右点指向v的左点,容量为1,费用为0;

4,终点右点向sink建边,容量为2,费用为0.

建好边,跑一次最大费用最大流,因为我们多算了一次起点和终点的点权,所以最后求出的最大费用要减去起点和终点的点权。



情况二:每个点无限走,问你从左上角到右下角走K次获取的最大权值和。


1,我们对可达边<u, v>处理,还是那句话————当选择一个点的左点或者右点时,都说明你选择了走这个点。

我们会考虑四种情况,题目要求————每个点可以走多次。所以我们如果选择一个点并不意味着一定要获取它的点权

如图:


显然有上面4种方式,因为我们不考虑是否获取点权。这就是说,当到达左点时,不一定非要选择到右点。 

当然这只是<u, v>边的情况,u每次可以选择向下走或者向右走,这样每一个点都会有8种选择(不考虑特殊的边界点)。

(1)u的左点连v的左点,说明不获取u的点权而获取v的点权,符合。

(2)u的左点连v的右点,说明既不获取u的点权也不获取v的点权,符合。

(3)u的右点连v的左点,说明既获取u的点权又获取v的点权,符合。

(4)u的右点连v的右点,说明获取u的点权而不获取v的点权,符合。

因此,我们可以建(1)(2)(3)(4)这四条边,边的容量为无穷大,因为我们可以任意选择经过该边的流量(不超过K的前提下),只要它能使最权值和最大化就行了。


2,拆点

如果我们可以走一个点多次,那么不管怎么样,从一个点出发只会有8种方式下传流量给另一个点(这里我们不考虑那些特殊的边界点)。我们会发现,在上述建边的前提下,已经包括了所有将流量传入下一点的方式。

这样的话我们只需要把每个点拆分成容量为1的边、并且保证超级源点到起点以及终点到超级汇点的边的容量为K————就可以保证最后的结果取的是走K次的最大权值和。




对于该问题的解决方案:设置超级源点source,超级汇点sink

1,source向起点左点建边,容量为K,费用为0;

2,拆点,每个点拆为容量为1,费用为点权的边;

3,<u, v>可达关系建四条边,这样的话对于非特殊边界点则可以建8条边(下、右都要建),边的容量为INF,费用为0;

4,终点到sink建边,容量为K,费用为0。

最后跑一次最大费用最大流,结果就是最大权值和。



  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值