网络流拓展五
uva 11082
题目要求
紫书P374
参考AC代码
|
|
思路
紫书P374
注意:
1.要把ab数组转换cd数组 建图里的点是每一行或每一列的和而非前缀和
2.注意输出矩阵的时候 j要从1开始 因为edges[i][0]里已经存了S到i的反向边了 该点要跳过
3.本题转换成网络流要把1-20转换成0-19 答案在+1
uva 1658
题目要求
紫书P375
参考AC代码
|
|
思路
紫书P375
注意:
1.问题等价于每个点只能经过一次且流量为2的mcmf 拆点
2.注意1到1+n和n到n+n要建一条流量为2或者inf的边 或者也可以设1+n为S n为T来避免这2条语句
uva 12264
题目要求
给n个点的无权无向图(n<=100),每个点有一个非负数ai。若ai==0则此点归敌方所有,若ai>0则此点归你且上面有ai个属于你的士兵。
保证至少有一个属于你的点与敌方的点相邻。你可以让你的每个士兵最多移动一次,每次可以待在原地或者去到相邻的属于你的领地,但每个点至少要留1各士兵,使得最薄弱的关口尽量坚固。
关口是指与敌方点相邻的点,薄弱与坚固分别指兵少与兵多
参考AC代码
|
|
思路
二分网络流
因为每个士兵只能移动一次 所以拆点 i到i+n连边 容量为a[i] 表示可以不移动
每个士兵人数大于0的点向S连一条边 容量为a[i]
对于每个士兵人数大于0的点 再遍历到达的终点 如果b[i]为0 记录下i的位置 表示该点是和敌兵相邻的点 否则i到j+n连一条容量为inf的边 表示士兵到相邻点的移动
再for一遍1到n 如果该点和敌兵相连 连一条容量为mid的流量到T 否则连一条容量为1的边到T 表示该点最少得有一个士兵(a[i]==0的点依旧跳过)
二分最大流即可
最小值最大:与敌兵相连的人尽可能平均 所以容量均设为mid 最大满流值下的mid
uva 1349
题目要求
紫书P375
参考AC代码
|
|
思路
紫书P375
每个点恰好属于一个有向圈==每个点只有唯一一个后继==完美匹配
网络流建图匹配
如果flow==n 说明满流 输出min_cost 否则输出N
uva 1515
题目要求
紫书P376
参考AC代码
|
|
思路
紫书P376
其实就是求最小割
首先把四周的.均换成# 计算出代价
所有的草地向S连边 若是四周的点 容量为inf 否则容量为d 所有洞和T相连 容量为d
代表把一块草地变成洞和洞变成草地的代价 接着矩阵的所有相邻边相连 容量为b
跑一边最大流 等值的最小割就是所求
最小割就是切断S和T的最小割 这里就是切断所有草地和洞的联系 只要满足切断的所有边使得草地无法到达洞 即为满足题意
uva 10735
题目要求
紫书P376-377
输出混合图的欧拉回路
参考AC代码
|
|
思路
紫书P377
有向边先存入ori 对无向边固定任意方向建图 若满流说明网络流能把那些多余的出度运送到T
对于有流量的边等价于这条变需要反向 那么反向存入ori
接着更新G数组让他对应ori 一遍dfs记录下路径 反向输出即可
注意:
1.vis是以edges里存的边的位置来判断有没有出现过 所以至少开500
2.注意输出格式 样例与样例之间有空行 提前输出不存在的时候也需要判断是否输出空行
uva 1659 && HDU 2982
题目要求
紫书P378
参考AC代码(寻找负费用增广圈)
|
|
参考AC代码(处理负权+重边)
|
|
思路
紫书P378
注意精度问题
思路1
只设一个源点S连向所有的点 容量为1费用为0 无汇点 正常按照边权取反建图
跑一边寻找负费用增广圈的mcmf即可
但方法一非常耗时
思路2
1.先将所有边权取反。
2.建边。正权值的边容量为1,费用为权值。负权值的边u->v拆成3条边,分别是S->v,v->u,u->T,容量都为1,v->u费用为负权的相反数,其他2条费用为0。
这样会出现某个点有多条边连到S或T,可以互相抵消到一方为0为止,统计剩下多少条k,将其中1条的容量设为k,其他的全部删掉。如果全部抵消掉了,那就将连S和T的边全部删掉。(这个删边的方法有技巧)
3.跑一次最小费用流得到的总费用,加上所有负权之和之后(注:此时答案已为负的),再取反即得到最大费用。
删边技巧是,在建这S->v,v->u,u->T 三条边时,先建中间那条,统计该点连到S几次,减去连到T点几次,结果若为正,则与S连一条边,容量就是几次,若负,同理。