深入浅出网络流

最小割

最大权闭合子图

闭合子图是什么?

就是一个有向无环连通图

最大权闭合子图就是说,图上的节点有正有负,我们要选出权值最大的点集。

建图过程:

  1. \(S\xrightarrow{w(i)} i\ (w(i)>0)\)
  2. \(i\xrightarrow{\infty} j\ ((i,j)\in E)\)
  3. \(i\xrightarrow{-w(i)}T\ (w(i)<0)\)

然后跑最大流,用\(\sum w(i)\ (w(i)>0)\)所有正权点的权值和)减去求出来的最大流(最小割)就是答案。

为什么要这样呢?

分类讨论:

  1. 如果正权边被割了,那就说明在最小割中,正权边\(\leqslant\)对面的负权边(否则被割掉的就不会是正权边而是负权边),对应的情况就是:选了正权边之后,正权边所连通的负权边比正权边还大(在绝对值上),这样选就亏本了,所以才需要割掉(在代码中就是从正权点的权值和中减去)。
  2. 如果负权边被割了,就说明正权边比负权边大,选了之后不会亏本,割掉的只是选了这个正权点所付出的最小成本。

(感觉这个是最小割当中最好理解的了……)


8.6 老师提了一个挺有意思的模型:

有若干个活动,分别需要一些房子。使用房子有两种方式:

  1. 每个活动分别租一间
  2. 直接买一间,这样每个活动都能使用,不需要再额外租。

就是说,一个负权点的代价可以有不止一种形式。

1.png

这样的话,原本那些连接正权点和负权点的,容量为\(\infty\)的边就有用了:


二选一模型

就是,一个节点有两种代价(或者收益),还有一些限制,让你找出最小的代价(最大的收益)

如果没有其他限制的话很简单:将两种代价(或者收益)一种连向\(S\),另一种连向\(T\),然后求出最小割,最小割就是最小的代价(如果是收益的话,就是必须要舍弃的最小收益)。

  1. 如果\(a\)被割给了\(S\)\(b\)被割给了\(T\),就有相应的代价;(双核CPU善意的投票
  2. 如果一个点集被割给了\(S\),就有相应的收益;(寿司餐厅Happiness小M的作物
  3. 如果一个点被割给了\(S\),并且一个点集\(V'\)中有一个点被割给了\(T\),就有相应的代价

第一种

\[S\xrightarrow{w(a)} a \xrightarrow{\text{代价}}b \xrightarrow{w'(b)}T \]

这样的话,求出最小割之后,割掉的就是最小的代价。

当然,像善意的投票就只需要根据意愿在\(S\)\(T\)之间二选一即可(代价还是照样连)

第二种

代价是用来最小化的,所以用最小割可以直接解决,那收益呢?

没关系,可以先把收益都加起来,然后再把收益当成代价去建弧,跑最小割。

这样,割掉的就是最小的收益,剩下的收益自然就是最大的了。

第三种

(记不得老师讲什么了,自己脑补的)

\[T\xleftarrow{w(a)} a \xleftarrow{代价} x(附加点) \xleftarrow{\infty}(v\in V')\xleftarrow{w(v)} S \]

(画反了,不想调)

(因为例题少所以就不讲了,反正最小割目前只接触了这两种模型)


二分图

\(\mathrm{DAG}\)最小路径覆盖

↑字面意思:用最少的路径(不是连接两个节点的)覆盖\(\mathrm{DAG}\)上所有的点(两条路径不能经过相同的点)。

魔术球问题

可以发现,如果把能够组合成完全平方数的数对连边,就会形成一个或以上的独立的\(\mathrm{DAG}\)

那问题就转化成了\(\mathrm{DAG}\)上的最小路径覆盖

首先,因为对于一个数,有两种流量流入:一种是其他(比它小的)数想要和它组成完全平方数;另一种是它自己要和比它大的数组成完全平方数

所以我们要将一个“数”拆成两个点:一个给比它小的点去连,另一个给它自己去连别人。

连边的话,将小数的点的入点连向大数的点的出点(前提是小数和大数的和是完全平方数),源点连向每个入点,每个出点连向汇点。

然后每次加入新数就连上相应的弧(比如将前面能够组成完全平方数的出点入点连弧),再在先前的残量网络上直接跑最大流,如果最大流没有增加,说明这个数不能与之前的所有数组成完全平方数,就把柱子的数量加一即可。


事实上,一般的最小路径覆盖也是差不多和上面一样的,但如果要你直接输出最小路径数的话

就输出\((N-最大流)\)就可以了。(这个不难理解吧)

最小点覆盖 & 最大独立集

先来一波定义

点覆盖:G任意边至少有一个顶点属于源点\(s\)的点集\(S\)

独立集:G中两两互不相连的点集\(S\)

最小点(权)覆盖:(点数/点权)最小的点覆盖;

最大点(权)独立集:(点数/点权)最大的点独立集。

最大流=最小割=最小点覆盖=\(N-最大独立集\)

上面很容易证:因为是最小割,所以只要把割边所连上的点删除,那么就能用最小的代价\(s\)\(t\)隔离开来。

可能还可以删掉其它的点(比如说你可以把和源点\(s\)直接相连的所有点都删掉,点集\(S\)就是与\(s\)直接相连的所有点),但是这样都没有最小割优。

然后,引入了一个点覆盖,就说明有一对点必须二选一,所以最大独立集就要\(-1\),因为点与点之间互不相连


如果是普通的最小点覆盖的话,容量设为\(1\)即可(当然,中间二分图的弧的容量还是\(\infty\))。

如果是最小点覆盖的话,把容量设为权值即可。


最后补充一个:二分图最大权匹配

按照费用流跑即可(应该要把费用取为负数再跑)

posted @ 2019-08-05 20:35  info___tion  阅读(228)  评论(5编辑  收藏  举报