KM算法

 

首先了解问题:也就是最大权值匹配;

二分图里,边带了权值,求整幅图里匹配最大/最小的权值

因为接触匈牙利算法的时候看的是找对象系列的博文,所以也自己写一发找对象的博文吧;

算法背景:

信息学院计算机某班级有5位玉树凌风的男子:小诸,小包,小许,小应,小章;

外语学院英语系某班级有5位国色天香的女子:小四,小雨,小美,小丽,小英;

名称不重要!强行变成X,Y,233333

然后5位男子对5位女子都有一个好感度,见表;

y0

y1

y2

y3

y4

x0

x1

x2

x3

x4

现在要给这几个男孩子找女朋友~使得他们所有好感度和最大。

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);

贴一发模板:

  1. bool Findpath(int u)
  2. {
  3. vx[u]=1;
  4. for(int i=1;i<=n;i++)
  5. {
  6. if(vy[i]) continue;
  7. int temp=lx[u]+ly[i]-ma[u][i];
  8. if(temp==0)
  9. {
  10. vy[i]=1;
  11. if(match[i]==-1||Findpath(match[i]))
  12. {
  13. match[i]=u;
  14. return true;
  15. }
  16. }
  17. else if(d>temp)
  18. d=temp;
  19. }
  20. return false;
  21. }
  22.  
  23. int KM()
  24. {
  25. memset(match,-1,sizeof(match));
  26. memset(lx,0,sizeof(lx));
  27. memset(ly,0,sizeof(ly));
  28.  
  29. for(int i=1;i<=n;i++)
  30. for(int j=1;j<=n;j++)
  31. lx[i]=max(ma[i][j],lx[i]);
  32.  
  33. for(int i=1;i<=n;i++)
  34. {
  35. while(1)
  36. {
  37. memset(vx,0,sizeof(vx));
  38. memset(vy,0,sizeof(vy));
  39. d=0x3f3f3f3f;
  40. if(Findpath(i)) break;
  41. for(int j=1;j<=n;j++)
  42. {
  43. if(vx[j]) lx[j]-=d;
  44. if(vy[j]) ly[j]+=d;
  45. }
  46. }
  47. }
  48. int res=0;
  49. for(int i=1;i<=n;i++)
  50. {
  51. res+=ma[match[i]][i];
  52. }
  53. return res;
  54. }

KM算法萌新讲解篇的更多相关文章

  1. jmeter正则表达式,萌新入门篇

    @@@@@@@@@@@@ 透过现象看本质 jmeter中正则表达式对我们来说,就是一个工具,他可以帮助我们做的事就是从一堆数据中截取出我们想要的字段,比如从setcookie:DERF12456DAS ...

  2. 萌新在线模板--keyboarder_zsq

    好像马上就要出去打铁了QAQ,所以是不是要做个模板带过去也玩一玩? 那就做吧... 标题就设为萌新模板吧...各种萌新讲解对吧.... 图论 拓扑排序 最短路 最小生成树 二分匹配 强连通Tarjan ...

  3. Unity萌新日记—开发小技巧与冷知识(脚本篇)

    在学习unity的过程中,总会遇到很多零碎的知识点和小技巧,在此把它们记录下来,方便日后查看. 第一篇是关于脚本的一些你可能不知道的小知识. 还是个正在学习的萌新,如果写的不好,请谅解. Unity版 ...

  4. KM算法(运用篇)

    传送门:KM算法---理解篇 最佳匹配 什么是完美匹配 如果一个二分图,X部和Y部的顶点数相等,若存在一个匹配包含X部与Y部的所有顶点,则称为完美匹配. 换句话说:若二分图X部的每一个顶点都与Y中的一 ...

  5. KM算法讲解

    对于二分图,我们可以用匈牙利来求出来最大匹配,但是如果给定每条边一个权值,我们要求这张图的最大匹配最大(小)权,单纯的用匈牙利就没法解决了,当然用费用流也可以做,但是代码较长,在处理完全二分图的时候时 ...

  6. 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱

    作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...

  7. KM算法(理解篇)

    转载:https://www.cnblogs.com/logosG/p/logos.html(很好,很容易理解) 一.匈牙利算法 匈牙利算法用于解决什么问题? 匈牙利算法用于解决二分图的最大匹配问题. ...

  8. 萌新带你开车上p站(番外篇)

    本文由“合天智汇”公众号首发,作者:萌新 前言 这道题目应该是pwnable.kr上Toddler's Bottle最难的题目了,涉及到相对比较难的堆利用的问题,所以拿出来分析. 登录 看看源程序 程 ...

  9. KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼

    感谢  http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...

随机推荐

  1. UVA 12130 - Summits(BFS+贪心)

    UVA 12130 - Summits 题目链接 题意:给定一个h * w的图,每一个位置有一个值.如今要求出这个图上的峰顶有多少个.峰顶是这样定义的.有一个d值,假设一个位置是峰顶.那么它不能走到不 ...

  2. arm处理器的历史及现状

    1 arm处理器的发展历史 arm1 arm2 arm3 arm6 arm7 arm9 arm11 arm cortex 2 arm处理器现状 arm cortex A a即application,即 ...

  3. Java笔记之利用反射访问或修改private成员

    对于类A.B,A是B的基类,A有一个私有成员name A.java public class A { private String name = "A"; public void ...

  4. meteor---在合并打包多个文件ZIP下载的功能

    实现多个文件边打包边下载的功能,速度还可以,本人亲测,欢迎大家来指点archiver --用NPM安装这个模块---本人文件存储在file-collection 中,可以用fs : fs.create ...

  5. 安装Nginx四层负载均衡

    Nginx1.9开始支持tcp层的转发,通过stream实现的,而socket也是基于tcp通信. stream模块默认不安装的,需要手动添加参数:–with-stream,官方下载地址:downlo ...

  6. Oracle中视图和同义词的区别

    视图和同义词分别都是数据库中的对象名称,它们都不对应实际的数据存储,都依赖其他对象的存在而存在.视图:视图可以被看成是虚拟表或存储查询.除非是索引视图,否则视图的数据不会作为非重复对象存储在数据库中. ...

  7. collectd+logstash+influxdb+grafana构建windows服务器应用监控系统

    一.背景介绍 本监控方案支持对Windows Server服务器集群的全面监控,方案提供丰富的图表展示, 以及对异常问题进行邮件的实时报警. 本系统由Collectd(操作系统数据搜集).logsta ...

  8. 使用TextTest来做认定测试——本质是通过diff对比程序的运行log输出,来看测试结果和预期结果是否相同

    Welcome to TextTest.org! TextTest is an open source tool for text-based functional testing. This mea ...

  9. bootstrap 学习笔记(3)---- 代码

    这节讲的是代码: 1.基本实例 <code></code>  <pre></pre> <kbd></kbd> 应用如下 1.Fo ...

  10. eclipse 查找controller

    一.打开eclipse: 二.同时按住Ctrl + Shift + R ; 弹出框如下: 在红色输入框内输入controller 名字即可. 查找控制器里面的方法:Ctrl + O