Network flow

Prime21

网络流问题

网络流问题算法一般比较固定。

求解最大流通用的算法是dinic和SAP。

求解费用流的通用算法是spfa+增广路/zkw

  在下面的问题中我们一般不考虑网络流的时间和空间复杂度问题。而是用建出的图的点数和边数来表示一个网络流复杂度。

当然,在一些问题中,可以证明网络流是等价于某一算法的话,复杂度和该算法相同。

最大流问题

问题类型:

  1. 就是类似网络流模型。
  2. 转化成一些等式,满足流量平衡关系。
  3. 二分图模型。

Medium

CQOI危桥

      Alice和Bob居住在一个由N座岛屿组成的国家,岛屿被编号为0到N-1。某些岛屿之间有桥相连,桥上的道路是双向的,但一次只能供一人通行。其中一些桥由于年久失修成为危桥,最多只能通行两次。
     Alice希望在岛屿a1和a2之间往返an次(从a1到a2再从a2到a1算一次往返)。同时,Bob希望在岛屿b1和b2之间往返bn次。这个过程中,所有危桥最多通行两次,其余的桥可以无限次通行。请问Alice和Bob能完成他们的愿望吗?

 

Medium

CQOI危桥

naive sol:

  建图方法:新建S,T。S向A1,B1连边,A2,B2向T连边,流量分别为An,Bn。其他边不变,危桥流量为1,其余为无穷大。判断是否满流。

  1. 设第一次中A1->B2的流量=B1->A2的流量=x
  2. 注意到是无向图,如果我们直接反过来,此时B2->B1的流量为Bn-x。如果此时流量有增加,不妨设A1->B1此时的流量为y。现在B2->B1还需要的流量即为y。
  3. 由于是无向图,所以B2->A1也可以走一个x的流量,那么A1->B1为y的流量转化为B2->A1->B1的流。另一边同理,至此证明方案可行。

这样做是不够的!我们需要交换B1,B2再判断一次。

proof:

Medium

混合图欧拉回路

一句话题意:给你一个图,其中有一些无向边和一些有向边,每条边只能走一次。问这个图是否存在一条欧拉回路。

对于左图,一条合适的欧拉回路是紫->蓝->橙->紫->灰->黑->红->黄->灰->绿->紫

Medium

挖掘问题实质:

  1. 我们发现实际上我们是给每条无向边做一个定向,使得存在欧拉回路。
  2. 回忆有向图是欧拉图的条件。基图连通,入度等于出度。
  3. 入度等于出度”!这和网络流中的流量平衡如出一辙!

Medium

下面的描述中,记录每一个点的入度-出度为

并把有向边删去,构建网络流。

构图一:

  建立一个新图:对于每个点建立一个点  ,对于每条边   ,附加S和T。S到每一个点   连一条流量为1的边,对于所有的   ,向T连一条流量为     的边,每条边所对应的点,向两个端点所对应的点连边,流量为1。求最大流,流量为m则欧拉回路存在。

v_i
viv_i
e_i
eie_i
e_i
eie_i
v_i
viv_i
in_i
iniin_i
in_i
iniin_i

构图二:

  先给每一条无向边任意定向,在原图中增加S和T。我们希望保留有流的定向,而把无流的边全部反向。考虑对于每一个点有流量平衡。有流入的弧的总数+无流出的弧的总数=in。in-出弧总数=有流入总数-有流出总数=k。 所以我们按K的正负决定向S,还是T连边。判断是否满流

Easy

JSOI 2010 Frozen Nova 

题目大意:在平面中有一些巫妖和一些小精灵,还有一些树会阻挡巫妖的视线。每一个巫妖都有一个攻击半径,如果一个小精灵在巫妖的攻击半径内,两点之间的连线没有树木阻挡,那么巫妖就可以秒杀小精灵。每个巫妖都有技能的CD。问最快多长时间可以使小精灵全灭。

强行题套题。先建立出能攻击的关系,然后按照时间二分,跑网络流判定是否可行即可。

Medium

[SCOI2012]奇怪的游戏

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

Medium

[SCOI2012]奇怪的游戏

需要推一推:

考虑对棋盘黑白染色。

设黑格上数字和为sumb,格子数为numb

设白格上数字和为sumw,格子数为numw

设最后都为每一个数都为x则:

 

 

numb-numw=0则需要二分x求出最小的x。

否则只需要验证当前x。

numb \times x - sumb = numw \times x -sumw
numb×xsumb=numw×xsumwnumb \times x - sumb = numw \times x -sumw
x=\frac{sumb-sumw}{numb-numw}
x=sumbsumwnumbnumwx=\frac{sumb-sumw}{numb-numw}

二分图

  1. 二分图的最大匹配数等于最小点覆盖数,即求最少的点使得每条边都至少和其中的一个点相关联,很显然直接取最大匹配的一段节点即可。
  2. 二分图的独立数(最大独立点集的点数)等于顶点数减去最大匹配数,很显然的把最大匹配两端的点都从顶点集中去掉这个时候剩余的点是独立集,这是|V|-2*|M|,同时必然可以从每条匹配边的两端取一个点加入独立集并且保持其独立集性质。
  3. 二分图问题的答案一般都是(N-匹配数)和匹配数。

Medium

uva 11082 Matrix Decompressing

A \in R^{R \times C}, A_{ij} \in [1,20] \cap \mathbb{Z}, R \leq 20, C \leq 20
ARR×C,Aij[1,20]Z,R20,C20A \in R^{R \times C}, A_{ij} \in [1,20] \cap \mathbb{Z}, R \leq 20, C \leq 20

定义如下参数:

RowSum(i)=\sum_{j=1}^{C} A_{ij}
RowSum(i)=j=1CAijRowSum(i)=\sum_{j=1}^{C} A_{ij}
CumulativeRowSum(i)=\sum_{k=1}^{i} \sum_{j=1}^{C} A_{kj}
CumulativeRowSum(i)=k=1ij=1CAkjCumulativeRowSum(i)=\sum_{k=1}^{i} \sum_{j=1}^{C} A_{kj}
ColumnSum(i)=\sum_{j=1}^{R} A_{ji}
ColumnSum(i)=j=1RAjiColumnSum(i)=\sum_{j=1}^{R} A_{ji}
CumulativeColumnSum(i) = \sum_{k=1}^{i} \sum_{j=1}^{R} A_{jk}
CumulativeColumnSum(i)=k=1ij=1RAjkCumulativeColumnSum(i) = \sum_{k=1}^{i} \sum_{j=1}^{R} A_{jk}

现在给出R,C,CRS,CCS,试求出满足条件的A

Sample input

3 4

10 31 58

10 20 37 58

\begin{bmatrix} 1 & 6 & 1 & 2\\ 1 & 2 & 2 & 16\\ 8 & 2 & 14 & 3 \end{bmatrix}
[16121221682143]\begin{bmatrix} 1 & 6 & 1 & 2\\ 1 & 2 & 2 & 16\\ 8 & 2 & 14 & 3 \end{bmatrix}
\begin{bmatrix} 1 & 1 & 1 & 7 \\ 1 & 1 & 7 & 12 \\ 8 & 8 & 9 & 2 \end{bmatrix}
[1117117128892]\begin{bmatrix} 1 & 1 & 1 & 7 \\ 1 & 1 & 7 & 12 \\ 8 & 8 & 9 & 2 \end{bmatrix}

Medium

uva 11082 Matrix Decompressing

其本质是一个二分图,把行当作X部,列当作Y部,那么中间的点,相当于限制了每条边的能流的上下界。

由于图的特殊性,我们只需要把每条边的上下界都减去1,跑一个可行流就可以了。

那么,更加一般的有上下界的流怎么实现呢?

Case1

无源汇有上下界流

fl_{up}
flupfl_{up}
fl_{low}
fllowfl_{low}
fl_{net}=fl_{up}-fl_{low}
flnet=flupfllowfl_{net}=fl_{up}-fl_{low}
fl_{net}
flnetfl_{net}
fl_{low}
fllowfl_{low}
fl_{low}
fllowfl_{low}

S

T

+\infty
++\infty
fl_{low}
fllowfl_{low}
fl_{low}
fllowfl_{low}
fl_{net}
flnetfl_{net}

为了减少边的数量,我们记录下列内容:

idea:

in[p]=\sum_{v} fl_{low}[v][p]
in[p]=vfllow[v][p]in[p]=\sum_{v} fl_{low}[v][p]
out[p]=\sum_{v} fl_{low}[p][v]
out[p]=vfllow[p][v]out[p]=\sum_{v} fl_{low}[p][v]
d[p]=in[p]-out[p]
d[p]=in[p]out[p]d[p]=in[p]-out[p]

如果d[p]>0则从S到p有边,否则p到T有边,容量为|d[p]|

Case2

有源汇有上下界的最大流

naive idea:

二分流量,加一条<T,S>有下界的边,直接变成Case1

new idea:

先引入新源新汇,将<T,S>边的界算作无穷大,将T->S的边、附加边断开,重新跑S->T的最大流。

bonus

这两个idea可以类似应用求解最小流

最小割问题

问题类型:

  1. 最小割=最大流
  2. 最小化代价
  3. 最大化利益,化为最小损失利用最小割解决

一般技巧:

S集和T集将表示两种不同的情况,中间的边割去,表示归属于另一边的代价。

Easy

文理分科

   给出一个nxm的座位表,每个同学学文或学理有一个喜悦度;并且如果两个挨着的同学一起学文或学理,会再有一个喜悦度加成。安排座位使得全班总的喜悦度最大。

Easy

文理分科

经典问题:

建图参考。

Medium

圈地计划

最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地。据了解,这块土地是一块矩形的区域,可以纵横划分为N×M块小区域。GDOI要求将这些区域分为商业区和工业区来开发。根据不同的地形环境,每块小区域建造商业区和工业区能取得不同的经济价值。更具体点,对于第i行第j列的区域,建造商业区将得到Aij收益,建造工业区将得到Bij收益。另外不同的区域连在一起可以得到额外的收益,即如果区域(I,j)相邻(相邻是指两个格子有公共边)有K块(显然K不超过4)类型不同于(I,j)的区域,则这块区域能增加k×Cij收益。经过Tiger.S教授的勘察,收益矩阵A,B,C都已经知道了。你能帮GDOI求出一个收益最大的方案么?

Medium

圈地计划

我们考虑黑白染色。

不同色的属于同样的集合我们视作在原问题中是不同的。

其余同文理分科。

Medium

HNOI2013切糕

Medium

HNOI2013切糕

  1. 先考虑没有光滑性限制。那么就是                    
  2. 现在我们考虑光滑性限制就是割断某条边的时候把被堵住的流给引到相邻的高度减去D的地方去。表示如果不堵住高度在这以上的边将会出事。
s \rightarrow k_1 \rightarrow k_2 \rightarrow \cdots \rightarrow k_{n+1} ->T
sk1k2kn+1>Ts \rightarrow k_1 \rightarrow k_2 \rightarrow \cdots \rightarrow k_{n+1} ->T

动态流问题

Easy

CTSC1999家园

  由于人类对自然的疯狂破坏,人们意识到在大约2300年之后,地球不能再居住了,于是在月球上建立了新的绿地,以便在需要时移民。令人意想不到的是,2177年冬由于未知的原因,地球环境发生了连锁崩溃,人类必须在最短的时间内迁往月球。 现有n个太空站处于地球与月球之间(编号1..n),m艘公共交通太空船在其中来回穿梭,每个太空站Si可容纳无限的人,每艘太空船pi只可容纳Hpi人。对于每一艘太空船pi,将周期性地停靠一系列的太空站(Si1,Si2…Sir),如:(1,3,4)表示停靠太空站1 3 4 1 3 4 1 3 4 …。 任一艘太空船从任一个太空站驶往另一个任意的太空站耗时为1。人只能在太空船停靠太空站(或地球、月球)时上船或下船。初始时的人全在地球上,太空船全在初始站(太空船pi处于Si1),目标是让所有的人尽快地全部转移到月球上。

Easy

CTSC1999家园

  这个问题被称为动态流问题。一般来说解决的策略是时间逐渐增加。

  我们考虑时间不断的增加,看什么时候会满流。我们附加源点和汇点。然后每次增加的边为上一个周期到这一个周期的边。为了保证可以无限停留,新建同一个对应点两个相邻时间直接无限大流量的边。

  当流量超过时,即为合法时间。

额外的hint:

  1. 原数据是错的。codevs的上面已经修正。
  2. 事实上,出题人当时好像通过打表推出了答案是一个关于k的分段线性函数。但是题解中并没有说明如何利用小的k的答案推出整个线性函数的方法。

Medium

[HNOI2007]紧急疏散

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

Medium

[HNOI2007]紧急疏散

不少人二分?可能有些问题。你能过旁边那个情况么?

X X D X X
X X . X X
X . . . X
X X D X X

  考虑正确做法是。我们不断的递增时间,

我们考虑出去的人只会增加不会减少。我们每一次对门都新开一个节点。这样就不会同一个时间出去两个人的可能。

费用流问题

问题类型:

  1. 就是费用流原模型。
  2. 费用不好表示,需要通过特殊的计算。
  3. 神级建模
  4. 平方费用关系

Easy

box

  一些盒子摆成环形,即1,n相邻,现在认为从相邻两个盒子之间移动一个球记为一次操作,一共有K(K<N)个球。现告诉你每个盒子里有几个小球,求最少多少次操作能每个盒子里的球数小于等于1。

(N<=10000)

  标算是一种奇怪的贪心虽然是O(n^2)的。很容易想到O(N^2)边数的网络流。O(N)边数其实只是在相邻的直接连边。感觉复杂度不对?前人的作业里证明了和贪心的复杂度等价。感觉不明觉厉。

Hard

NOI 2008 志愿者招募

  申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管。布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者。经过估算,这个项目需要N 天才能完成,其中第i 天至少需要Ai 个人。 布布通过了解得知,一共有M 类志愿者可以招募。其中第i 类可以从第Si 天工作到第Ti 天,招募费用是每人Ci 元。新官上任三把火,为了出色地完成自己的工作,布布希望用尽量少的费用招募足够的志愿者,但这并不是他的特长!于是布布找到了你,希望你帮他设计一种最优的招募方案。

Hard

NOI 2008 志愿者招募

  1. 我们设第i类志愿者的雇佣人数为x[i]。第j天的总雇佣人数为p[j]
  2. 那么对于每一天有p[j]>=a[j]
  3. 我们对于每一个式子加入辅助变量y[j](y[j]>=0)以消去不等号,p[j]=a[j]+y[j]
  4. 记p[0]=0,p[n+1]=0。p[j]与p[j-1]的等式作差可得一些等式。其中每一个变量x[i],y[j]只出现了两次,一正一负。
  5. 考虑这些式子与流量平衡是类似的。我们可以建立出对应的边。至此,问题得到解决。

 

 

来自byvoid的题解

Made with Slides.com