• 二分图若干


    二分图

    0x00 简介

    • 什么是二分图?
    • 顾名思义,就是能分成两个部分的图
    • 如果把这两部分分别叫做{U},{V},我们规定,如果存在一种U、V的划分,使所有图中的边<u,v>,不存在u,v在同一个集合(同时在{U}或者{V}),那么这个图就是二分图
    • 这个性质有什么用呢?
    • 我们发现可以把一个集合摆在左边,另一个集合摆在右边,然后所有原图中的边都是从左边连到右边,没有左-左和右-右的边
    • 然后我们就可以干一些神奇的事

    0x01 最大匹配

    • 一个班级里有一些男女同学,一些同学之间了美好的情感,我们希望找一个最大匹配,就是希望找到最多对有好感的同学,把他们两两配对且没有冲突
    • 我们发现男女同学构成的关系网是一张二分图(没有男-男,女-女的边)
    • 于是乎问题就变成了一个二分图最大匹配问题,一个二分图中不存在奇环(简单可证),所以我们有神奇的办法解决这个问题

    网络流!

    • 从S向男孩子连容量为1的边,从男孩子向他喜欢的女孩子连容量为1的边,从女孩子向T连容量为1的边
    • 求最大流,正确性很显然
    • 就是常数有点大

    匈牙利算法

    • 我们发现,如果我们从一个没有妹子的男生出发,走一条男-女-男-女-男-女……的链,并且匹配边与不匹配边交错,最后以一个没匹配到的妹子结束

    • 像这样

    • 男 --- 不匹配 --- 女 --- 匹配 --- 男 --- 不匹配 --- 女

    • 然后我们把路径上所有的匹配与不匹配取反

    • 变成这样

    • 男 --- 匹配 --- 女 --- 不匹配 --- 男 --- 匹配 --- 女

    • 我们发现,这样没有影响匹配不冲突的性质,并且总的匹配数量+1

    • 我们就可以不断的重复这个过程,不断地使匹配数+1,直到找不到这样的链为止

    • 这样的链叫做增广路

    HK算法

    • 全名叫什么我也记不得了
    • 这是一个对匈牙利算法的优化
    • 我们发现,一次DFS找增广路的时间和增广路的长度息息相关,这和网络流是类似的(我们也希望找一条长度最短的增广路)
    • 那我们怎么优化网络流呢?
    • Dinic!对顶点进行距离标号,只允许距离+1的增广
    • 这里也可以类比这样的做法,对二分图进行距离标号,只允许距离+1的增广
    • 然后跑匈牙利就可以啦!跑是最快的,比Dinic求最大匹配快的多

    0x02 最大权完备匹配

    • 有的时候,同学们之间的情感是不等的,一些同学们之间君子之交,而另一些同学们干柴烈火
    • 然后我们希望找一种最干柴烈火的配对方案
    • 这就需要最大权匹配

    费用流!

    • 从S向男孩子连容量为1费用为0的边,从男孩子向他喜欢的女孩子连容量为1费用为这个配对的权值的边,从女孩子向T连容量为1费用为0的边
    • 求最大费用最大流,正确性很显然
    • 就是常数有点大

    KM算法

    • KM算法要求一张完全二分图!!!如果不是完全二分图得补成完全二分图!!!
    • 我们考虑给男孩子和女孩子都维护一个期望值,只有一组男女配对满足:男孩子的期望+女孩子的期望 == 这组配对的权值 ,我们才认可这对配对
    • 并且时刻保持对于所有的配对,都有 男孩子的期望+女孩子的期望 >= 这组配对的权值
    • 这样如果我们对于期望进行一些调整,并且满足上面两个性质的前提下,找到了一种完备匹配(所有人都匹配上了),那么这种匹配是权值最大的
    • 显然此时的匹配权值就是男女同学的期望值之和,考虑到这一点,KM算法的正确性就不难理解了
    • 正确性解释:我们考虑二分图的任何一个匹配,它的权值可能大于任意时刻的期望值之和么?
    • 不可能,显然任何一组匹配里每个男孩和女孩都只出现了一次,因此由第二条性质我们可以推导出 (sum)男孩子的期望+(sum)女孩子的期望 >= 任何一组匹配权值
    • 所以如果我们能够取等了,那么此时就是最大匹配
    • 那么我们如何修改期望呢?
    • 考虑某个时刻,如果我们发现此时的期望太高,不能为一个男孩子找到配对,那么我们要考虑降低期望
    • 首先,本来能认可的配对显然还需要继续认可,然后我们应该新加入一些认可的匹配。由于不能删去本来认可的匹配,我们发现本来认可的匹配两边一定是一边加一边减,而且数值相同。我们考虑这个男孩子匹配的过程,一定是由于他所有喜欢的都女孩子被另一些男孩子抢了,并且找不到增广路,所以才会导致匹配不存在。
    • 那我们要让期望降低多少,才能加入一个配对呢?
    • 我们考虑找增广路的过程,一定有某个时刻一个没匹配上的男孩子被拒绝了,原因是配对权值不等于期望之和,那么这个男孩子要降低一些期望,才能加入一些配对,要降低的最少期望等于他所有被拒绝的经历中,离目标最近的那一个,设这次的差为delta
    • 我们发现找增广路的过程中一定是左右左右左交替,并且以左开始,以左结束,死在一个找不到增广路的男孩子身上,这样的话我们取所有男孩子的delta的最小值d,把增广路上所有男孩子的期望降低d,所有女孩子的期望增加d
    • 这样,所有原来在匹配中的边还在匹配里,并且由于左边的点比较多,总的期望下降了一点
    • 不断重复这个过程,直到找到完备匹配
    • 具体实现看代码
    • 一个优化!将原来的匈牙利DFS找增广路改成BFS,不然会被卡掉!!

    Extra

    • 如果我们要求非完全二分图最大权匹配,不要求全部匹配上呢?
    • 对于费用流做法,只要增广的费用小于零就停止不做了
    • 对于KM做法,补上一些权值为0的配对补成完全图就可以了
    • 如果我们要求非完全二分图最大权匹配,要求全部匹配上呢?
    • 对于费用流做法,正常搞就可以了
    • 对于KM做法,补上一些权值为-INF的配对补成完全图
    许愿弥生改二
  • 相关阅读:
    windbg 调试 winform程序(二车间机台程序)
    jquery操作数组的方法
    kafka之consumer参数auto.offset.reset
    常用linux脚本记录
    linux 常用命令总结
    华为S系列交换机配置
    python画冰墩墩
    进程间通信——IPC之共享内存
    ARP绑定IP和MAC的作用
    谷粒商城中renrenfast报错Error creating bean with name 'ossClient'
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6745508.html
Copyright © 2020-2023  润新知