POJ2175-消圈算法

题意:

一个城市中有n个大楼,m个避难所,接下来给出n个大楼的坐标和人数,接下来m行给出每个避难所的坐标和容纳量,大楼到避难所的距离定义为曼哈顿距离+1,然后给出n行m列数据,第i行第j列代表从第i个大楼到第j个避难所去的人数,保证此方案合法,然后判断此方案是否所有人到避难所的距离和最小,是的话输出OPTIMAL,否则给出更好的方案,但不一定是最优的;

思路:

如果用最小费用最大流算法直接求解,会超时,此时有个更巧妙的算法,因为题目中已经给出了一套方案,然后就利用给出的方案建立残留网络图,寻找是否存在负圈,存在的话肯定不是最优,找到这个负圈,顺着负圈增广,得到一个更优(不一定最优)的解就行了,题目不要求最优。

所谓消圈定理,就是在某个流 中,如果其对应的残余网络(剩余流量为 0 的边视为不存在)没有负圈,那它一定就是当前流量下的最小费用流。反之亦然。即「 是最小费用流等价于其残余网络中没有负圈」。

建图是关键。建残量网络,每条边只需要一个剩余流量remains和代价cost即可,剩余流量为0意味着残量网络中不存在这条边。remains(i, j)表示 i 到 j 的残量,那么
在这里插入图片描述
比如上面这个边,u到v容量是11,流量是5,那么remain(u , v) = 11 - 5 = 6; 而remian(v , u) = 5(cap(v , u) = 0, flow(v , u) = -5)。对于正向弧(i,j),flow(i,j) = remain(j,i)。只要把remains更新好,最后输出flow时转成反向弧输出就好了。
建筑 i 到防空洞 j 的容量可设为INF,输入给出了流量,则remains(i , j) = INF - f, cost = …;
相应反向弧remains(j , i) = f,cost取反;
建立源点s, 设建筑 i 的流出的流量和为tot1[i], 而s 到 i 的容量为B[i].c(建筑i的人数),其残量为B[i].c - tot1[i].。
汇点同理。

邻接表

#include <cstdio>
#include <queue>
#include <vector>
#include <cst
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值