KM算法萌新讲解篇
KM算法
首先了解问题:也就是最大权值匹配;
二分图里,边带了权值,求整幅图里匹配最大/最小的权值
因为接触匈牙利算法的时候看的是找对象系列的博文,所以也自己写一发找对象的博文吧;
算法背景:
信息学院计算机某班级有5位玉树凌风的男子:小诸,小包,小许,小应,小章;
外语学院英语系某班级有5位国色天香的女子:小四,小雨,小美,小丽,小英;
名称不重要!强行变成X,Y,233333
然后5位男子对5位女子都有一个好感度,见表;
|
y0 |
y1 |
y2 |
y3 |
y4 |
|
|
x0 |
4 |
1 |
6 |
2 |
3 |
|
x1 |
5 |
0 |
3 |
7 |
6 |
|
x2 |
2 |
3 |
4 |
5 |
8 |
|
x3 |
3 |
4 |
6 |
3 |
4 |
|
x4 |
4 |
6 |
5 |
8 |
6 |
现在要给这几个男孩子找女朋友~使得他们所有好感度和最大。
KM算法步骤:
初始情况下把好感度都放在男子的集合上,即
LX0=6;
LX1=7;
LX2=8;
LX3=6;
LX4=8;
然后枚举X集合元素去匹配,如果匹配到的边wij=LXi+LYj,并且j还不存在配偶,那么,嘿嘿嘿,就让他们牵手~(✿◡‿◡)
比如:在枚举X集合时,X0-Y2;X1-Y3;X2-Y4;
但是,有些女孩子很受欢迎,突然到了X3,X3最喜欢Y2,而Y2已经有X0喜欢了,窝们的目的是让整个好感度最大;
那么就会有两种情况:
① :我让X0再去找一个,然后让X3-Y2;
② :我让X3另外去选,然后还是让X0-Y2;
那么窝们怎么能随随便便让男孩子另外去找一个呢,窝们其实很容易想到一个方案就是让一个男孩子去找另外一个女孩子使得好感度比原先大的好感度降低的越少,那么这样还是会让总好感度最大;
具体的方法就是窝们可以开一个差值数组代表最大的好感度和其他好感度的差;
然后每次在寻找女朋友的时候将这个差值数组进行更新;
每次扫完女孩子以后,如果没有找到心仪对象,
找到那个最小差值d
把LX数组种那些有矛盾的男孩子的值-=d;
把LY数组种那些引起矛盾的女孩的值+=d;
观察窝们说一个男孩子找到女朋友的条件是:如果匹配到的边wij=LXi+LYj,并且j还不存在配偶,那么,嘿嘿嘿,就让他们牵手~(✿◡‿◡)
这样就能保证在下次找配偶的过程中
1.LX-=d,当再次对当前有矛盾的男孩子寻找时可能一下子找到那个好感度减少最少的女孩,因为LX减少,然而LY不变,所以一旦满足条件,就返回true;
2.LY+=d,引起矛盾的那个女生还是照样引起矛盾或者在之前就被寻找过在下次寻找到时不寻找;
3.在对出现矛盾的那个女生的本来配好的男朋友进行寻找时,同理1的情况,找到那个好感度减少最少的女孩且满足情况就返回;
这样算法流程说明(个人理解):
LX的作用是维护权值减少最少,LY的作用是维护权值最大的依旧最大;
教科书术语:
(1) 令(u,v)是一个覆盖,如对于每个j,ui=max(wij),vi=0;
(2) 在Ku*v中找出一个最大匹配M。如果M是一个完美匹配,停止并将M作为最大权值匹配返回。否则,令Q是Ku*v中大小为M的一个定点覆盖。设R=Q∩X,T=Q∩Y。令e=min{ui+vj-wij,xi∈X-R,yi∈Y-T}。
(3) 对于xi∈X-R,从ui中减去e.对yi∈T,把e加到vj上,形成一个新的相等子图,转向步骤(2);
贴一发模板:
bool Findpath(int u)
{
vx[u]=1;
for(int i=1;i<=n;i++)
{
if(vy[i]) continue;
int temp=lx[u]+ly[i]-ma[u][i];
if(temp==0)
{
vy[i]=1;
if(match[i]==-1||Findpath(match[i]))
{
match[i]=u;
return true;
}
}
else if(d>temp)
d=temp;
}
return false;
} int KM()
{
memset(match,-1,sizeof(match));
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly)); for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
lx[i]=max(ma[i][j],lx[i]); for(int i=1;i<=n;i++)
{
while(1)
{
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
d=0x3f3f3f3f;
if(Findpath(i)) break;
for(int j=1;j<=n;j++)
{
if(vx[j]) lx[j]-=d;
if(vy[j]) ly[j]+=d;
}
}
}
int res=0;
for(int i=1;i<=n;i++)
{
res+=ma[match[i]][i];
}
return res;
}
KM算法萌新讲解篇的更多相关文章
- jmeter正则表达式,萌新入门篇
@@@@@@@@@@@@ 透过现象看本质 jmeter中正则表达式对我们来说,就是一个工具,他可以帮助我们做的事就是从一堆数据中截取出我们想要的字段,比如从setcookie:DERF12456DAS ...
- 萌新在线模板--keyboarder_zsq
好像马上就要出去打铁了QAQ,所以是不是要做个模板带过去也玩一玩? 那就做吧... 标题就设为萌新模板吧...各种萌新讲解对吧.... 图论 拓扑排序 最短路 最小生成树 二分匹配 强连通Tarjan ...
- Unity萌新日记—开发小技巧与冷知识(脚本篇)
在学习unity的过程中,总会遇到很多零碎的知识点和小技巧,在此把它们记录下来,方便日后查看. 第一篇是关于脚本的一些你可能不知道的小知识. 还是个正在学习的萌新,如果写的不好,请谅解. Unity版 ...
- KM算法(运用篇)
传送门:KM算法---理解篇 最佳匹配 什么是完美匹配 如果一个二分图,X部和Y部的顶点数相等,若存在一个匹配包含X部与Y部的所有顶点,则称为完美匹配. 换句话说:若二分图X部的每一个顶点都与Y中的一 ...
- KM算法讲解
对于二分图,我们可以用匈牙利来求出来最大匹配,但是如果给定每条边一个权值,我们要求这张图的最大匹配最大(小)权,单纯的用匈牙利就没法解决了,当然用费用流也可以做,但是代码较长,在处理完全二分图的时候时 ...
- 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- KM算法(理解篇)
转载:https://www.cnblogs.com/logosG/p/logos.html(很好,很容易理解) 一.匈牙利算法 匈牙利算法用于解决什么问题? 匈牙利算法用于解决二分图的最大匹配问题. ...
- 萌新带你开车上p站(番外篇)
本文由“合天智汇”公众号首发,作者:萌新 前言 这道题目应该是pwnable.kr上Toddler's Bottle最难的题目了,涉及到相对比较难的堆利用的问题,所以拿出来分析. 登录 看看源程序 程 ...
- KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼
感谢 http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...
随机推荐
- 封装EF code first用存储过程的分页方法
一年半没有做过MVC的项目了,还是很怀念(因为现在项目还是原来的ASPX),个人还是喜欢mvc,最近又开始重拾MVC,感觉既熟悉又陌生. 记录一下封装好的分页代码 首先先说下 我使用EF codefi ...
- redis的主从复制和哨兵支持的主从切换
1 主从复制的目的是为了读写分离 master写,然后同步到slave,slave只管读. 2 哨兵存在的目的 是为了主从切换,如果master挂了,那么一个slave成为master,重启之后的ma ...
- java之折半查找
//功能:二分查找import java.util.*; public class Demo1 { public static void main(String[] args) { int arr[] ...
- Windows10搭建FTP服务器
配置FTP服务器步骤: 第一步: 打开控制面板--->选择程序--->启动或关闭Windows功能--->勾选FTP服务器等.如下图: 第二步: 右键此电脑--->点击管理-- ...
- [Java多线程] volatile 关键字正确使用方法
volatile 变量具有 synchronized 的可见性特性,但是不具备原子特性,即多线程环境中,使用 volatile 关键字的变量仅可以保证不同线程读取变量时,可以读到最新修改的变量值,但是 ...
- java后台判断发布的图片是否存在
x现在已知一个固定格式的图片,判断图片是否存在例如,http://127.0.0.1/image/201709091300.jpg import java.net.URL;import java.ne ...
- linux LVM:物理卷逻辑卷
逻辑卷管理器,当分区不够用的时候,可以新建一个更大的分区再复制进去,但是浪费时间.Lvm可以弹性调整分区大小,可以动态组合分区.分区大小固定了就无法调整, apt-get update & a ...
- 向HTML页面传入参数
这次是想将参数传入HTML页面,通过js获取参数信息,动态生成HTML页面内容: 方法一: <script> function GetArgsFromHref(sHref, sArgNam ...
- platform_set_drvdata和platform_get_drvdata用法【转】
本文转载自:http://www.cnblogs.com/wangxianzhen/archive/2013/04/09/3009530.html 在用到Linux设备驱动的platform框架时,常 ...
- UVA1482 Playing With Stones —— SG博弈
题目链接:https://vjudge.net/problem/UVA-1482 题意: 有n堆石子, 每堆石子有ai(ai<=1e18).两个人轮流取石子,要求每次只能从一堆石子中抽取不多于一 ...