网络流一般化建模方式/最大流篇

最大流模板

分配类型问题:

将物资均匀分配到多个点上。

典型例子:网络流24题圆桌问题/试题库问题/分配问题

一般化建模方式:将每个可分配的点连上源点,容量为可分配流量数;将每个待分配的点连上汇点,容量为待分配流量数;

点之间按题目关系连边,容量按题目而定(1或者inf),最大流即可。

例题:

【tyvj1431】分配任务

随着tyvj发展越来越大,管理员的任务越来越重,如何合理的分配任务,成为了一个可研究的命题。Tyvj当前一共有M个需要做的任务,和N位管理员。每一个管理员的上线时间并不是固定的,每一个人有d[i]单位的上线时间,每一位管理员一个单位的时间可以完成一个任务,且一个任务只能由一个管理员来完成(如果更多的管理员参与进来,可能会造成混乱)。每一位管理员的能力有所不同,所以能完成的任务集合可能不相同。最终让所有未完成的任务数量最少。

题解:跟圆桌问题一模一样,原点向所有管理员连容量为d[i]的边,管理员向可解决的任务连1的边,任务向汇点连1的边,ans=m-最大流。

 

图上流量/边点覆盖问题:

在一个图上进行操作。

典型例题:最小路径覆盖问题

一般化建模方式:将每个点拆为入点和出点,再按题目要求连边。

例题:

【bzoj3504】[Cqoi2014]危桥

Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。Alice希望在岛屿al和a2之间往返an次(从al到a2再从a2到al算一次往返)。

同时,Bob希望在岛屿bl和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?

 

题解:按原图建图,普通桥为容量为inf的边,危桥为容量为2的边,

然后先从源点到al连容量为2*an的边(往返=一条边走两次),a2到汇点连容量为2*an的边,

源点到bl连容量为2*bn的边,b2到汇点连容量为2*bn的边,跑一边最大流,如果小于2*an+2*bn则无解。然后交换a2,b2,再跑最大流,如果小于2*an+2*bn则无解。

 

【bzoj2718/1143】[Violet 4]毕业旅行


题解:最小路径覆盖的改版。求最长反链。

关于链和反链:http://vfleaking.blog.163.com/blog/static/1748076342012918105514527/

floyd传递闭包。然后按最小路径覆盖建边(把两点有边换成可到达),跑最大流,ans=点数-最大流。

【bzoj2095】[Poi2010]Bridges

YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛。现在YYD想骑单车从小岛1出发,骑过每一座桥,到达每一个小岛,然后回到小岛1。霸中同学为了让YYD减肥成功,召唤了大风,由于是海上,风变得十分大,经过每一座桥都有不可避免的风阻碍YYDYYD十分ddt,于是用泡芙贿赂了你,希望你能帮他找出一条承受的最大风力最小的路线。

题解:先二分答案,然后就变成了找混合图是否存在欧拉回路的问题。

令每个点的入度- 出度为它的度差。对于每条无向边u<>v,先定向为u>v

考虑变更它的方向,会使得u 的度差+2, v 的度差-2。故对于点u,若度差为奇数则没有欧拉回路;

否则若度差为负,从S u 连容量为度差/ - 2 的弧,若度差为正,从u T 连容量为度差/2 的弧。

对于每条无向边u<>v,从u v 连容量为1 的弧。满流即存在欧拉回路。

 

棋盘/格点类问题:

在四连通棋盘上进行操作。

一般化建模方式:二分染色,黑白格分别连源点和汇点。/每行每列分别建一个点

例题:

【bzoj2756】[SCOI2012]奇怪的游戏

Blinker 最近喜欢上一个奇怪的游戏。
这个游戏在一个N*M 的棋盘上玩,每个格子有一个数。每次 Blinker 会选择两个相邻的格子,并使这两个数都加上 1。
现在Blinker 想知道最少多少次能使棋盘上的数都变成同一个数,如果永远不能变成同一个数则输出-1。

 

题解:先二分染色。设最后变为x。设白格数量为num1,格上数字总和为sum1;黑格数量为num2,格上数字总和为sum2.

则检查x是否可行的方法是:

源点向白格连边,容量为x-格点值;黑格向汇点连边,容量为x-格点值;

黑白格之间连容量为inf的边。如果最大流=x*(num1+num2)-sum1-sum2则有解。

因为每次操作会使一个黑格和一个白格的值同时加1

则(x*num1-sum1=(x*num2)-sum2

所以x=(sum1–sum2)/(num1–num2)

num1-num2不等于0时(即格子数为奇数)x可以直接解出,然后网络流验证。

当num1=num2时用二分验证。

次数=最大流/2(因为每次操作增加两个点的权值)

 

【bzoj1458】士兵占领

有一个M* N的棋盘,有的格子是障碍。现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵。我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵, 第j列至少放置了Cj个士兵。现在你的任务是要求使用最少个数的士兵来占领整个棋盘。

 

题解:每一行建一个点,每一列建一个点。先假设所有点都放满了士兵,现在要求的就是最多可以拿走多少个士兵。

源点向每一行连边,容量为总放置士兵数-Li;每一列向汇点连边,容量为总放置士兵数-Cj,如果某行和某列有非障碍交点,则在该行和该列间连容量为1的边,ans=总可放置兵数-最大流。

 

匹配类问题:

求多个点之间最大流量/匹配数。

一般化建模方式:二分图匹配/拆点限流

典型例题:飞行员配对方案问题

例题:

BZOJ1433 假期的宿舍

题解:分成两边,回家的和不回家的/新来的。两边分别向源点/汇点连容量为1的边。如果某两人认识且分属两边则连容量为1的边。满流则有解。

【bzoj1305】[CQOI2009]dance跳舞

一次舞会有n个男孩和n个女孩。每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首(或更多)舞曲。有一些男孩女孩相互喜欢,而其他相互不喜欢(不会单向喜欢)。每个男孩最多只愿意和k个不喜欢的女孩跳舞,而每个女孩也最多只愿意和k个不喜欢的男孩跳舞。给出每对男孩女孩是否相互喜欢的信息,舞会最多能有几首舞曲?

题解:注意到每人不会和同一人跳2次及以上和最多k个人这两个性质。必须拆点限流+二分答案。

每个人拆成xi,yi两个点。喜欢则从xi向xj连容量为1的边,不喜欢则从yi向yj连容量为1的边。

然后再从xi向yi,xj向yj连容量为k的边。最后二分答案a,由源点向xi(男)连容量为a的边,xj(女)向汇点连容量为a的边,看是否满流即可。

【bzoj1711】[Usaco2007 Open]Dingin吃饭

农夫JOHN为牛们做了很好的食品,但是牛吃饭很挑食. 每一头牛只喜欢吃一些食品和饮料而别的一概不吃.虽然他不一定能把所有牛喂饱,他还是想让尽可能多的牛吃到他们喜欢的食品和饮料. 农夫JOHN做了F (1 <= F <=100) 种食品并准备了D(1 <= D <= 100) 种饮料. 他的N (1 <= N <= 100)头牛都以决定了是否愿意吃某种食物和喝某种饮料. 农夫JOHN想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料. 每一件食物和饮料只能由一头牛来用. 例如如果食物2被一头牛吃掉了,没有别的牛能吃食物2.

 

题解:三分图匹配。源点向每个食物连容量为1的边,每个食物向可以吃它的牛连容量为1的边,

每个牛向可以喝的饮料连容量为1的边,每个饮料向汇点连容量为1的边,跑最大流即可。

 

时间问题:

在网络流中加入时间变量。

一般化建模方式:按时间拆点。

典型例题:星际转移问题

例题:

【bzoj1189】[HNOI2007]紧急疏散evacuate

发生了火警,所有人员需要紧急疏散!假设每个房间是一个N M的矩形区域。每个格子如果是’.’,那么表示这是一块空地;如果是’X’,那么表示这是一面墙,如果是’D’,那么表示这是一扇门,人们可以从这儿撤出房间。已知门一定在房间的边界上,并且边界上不会有空地。最初,每块空地上都有一个人,在疏散的时候,每一秒钟每个人都可以向上下左右四个方向移动一格,当然他也可以站着不动。疏散开始后,每块空地上就没有人数限制了(也就是说每块空地可以同时站无数个人)。但是,由于门很窄,每一秒钟只能有一个人移动到门的位置,一旦移动到门的位置,就表示他已经安全撤离了。现在的问题是:如果希望所有的人安全撤离,最短需要多少时间?或者告知根本不可能。

题解:两种做法:二分和枚举。枚举会超时,所以只能二分。

首先,每个门来一次bfs,求出每个人到这扇门的时间。然后二分时间t,

源点向每个空地连容量为1的边,每个空地向可以到达的门连容量为1的边,每扇门拆成t个点,都向汇点连边,如果流量=人数则有解。

【tyvj1517】飘飘乎居士的乌龟

飘飘乎居士的乌龟被安置在了m个窝中。现在,飘飘乎居士已经接到了n个人的定购通知,他们会按顺序在来挑选乌龟,其中,第i个人会在pi个窝中挑选乌龟,但最多只想买xi只乌龟。另外,在第i个人购买完乌龟以后,飘飘乎居士会将指定的qi个窝中的龟进行调整,他可以任意调换指定的qi个窝中乌龟数量。飘飘乎希望知道,在n个人购买完乌龟后,他最多可以出售多少只乌龟?

题解:将每个窝拆成n个点。源点向刚开始的每个窝连容量为mi的边,每个窝向它在下一个时间的点连容量为inf的边;

如果在时间i可调整不同窝内乌龟数量,则在不同的窝在时间i的点之间连容量为inf的边;

每个窝在时间i的点向第i个可以在此窝中挑选乌龟的人连容量为inf的边,每个人向汇点连容量为xi的边,跑最大流即可。

你可能感兴趣的:(网络流一般化建模方式/最大流篇)