• 深入浅出网络流


    最小割

    最大权闭合子图

    闭合子图是什么?

    就是一个有向无环连通图

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

    建图过程:

    1. (Sxrightarrow{w(i)} i (w(i)>0))
    2. (ixrightarrow{infty} j ((i,j)in E))
    3. (ixrightarrow{-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),就有相应的代价

    第一种

    [Sxrightarrow{w(a)} a xrightarrow{ ext{代价}}b xrightarrow{w'(b)}T ]

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

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

    第二种

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

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

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

    第三种

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

    [Txleftarrow{w(a)} a xleftarrow{代价} x(附加点) xleftarrow{infty}(vin 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))。

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


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

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

  • 相关阅读:
    suse12安装详解
    Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
    菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]
    openstack中dashboard页面RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
    Multiple network matches found for name 'selfservice', use an ID to be more specific.报错
    查看 SELinux状态及关闭SELinux
    SELinux深入理解
    IP地址、子网掩码、网络号、主机号、网络地址、主机地址
    Oracle job procedure 存储过程定时任务
    POI文件导出至EXCEL,并弹出下载框
  • 原文地址:https://www.cnblogs.com/info---tion/p/11305399.html
Copyright © 2020-2023  润新知