KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权。

经典算法,想不出来的了,要參考别人的。然后消化吸收吧。

由于真的非常复杂的算法。

我理解算法匹配思想:

1 開始的时候,全部边都记录自己的最优匹配,无论有没有冲突

2 递归循环的时候。假设找不到自己的最优匹配,那么就找次要匹配

3 次要匹配不行,继续找下一个次优匹配,全部点都一定要找到解

难点:

怎样记录这些信息,以便循环处理全部点。

牵涉到非常多什么增广路,交错树之类的,名词,术语,变量就一大堆。

心浮气躁可不能学这种算法了,要心平气和,深呼吸,然后慢慢消化才行。

这个博客分析挺具体的。且带图:

http://blog.csdn.net/wuxinxiaohuangdou/article/details/14056987

http://blog.csdn.net/ZYY173533832/article/details/11519291

两个博客一样的图,也不知道谁抄谁的了。

我以下算法是略微改动一点而成的程序。

主要是slack能够不使用数组记录,仅仅须要记录当前的得到的最小值就能够了。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. #include <limits.h>
  5. using namespace std;
  6.  
  7. const int MAX_N = 301;
  8. int N;
  9. int link[MAX_N];//右边到左边的连线
  10. int slack;//当前dfs中,訪问了的点中能够让利的最小限度
  11. bool visLeft[MAX_N], visRight[MAX_N];
  12. int curMaxVal[MAX_N], giveAwayVal[MAX_N];
  13. int gra[MAX_N][MAX_N];
  14.  
  15. bool Hungary(int u)
  16. {
  17. visLeft[u] = true;
  18. for (int v = 1; v <= N; v++)
  19. {
  20. if (visRight[v]) continue;
  21. int curSlack = curMaxVal[u] + giveAwayVal[v] - gra[u][v];
  22. if (curSlack == 0)
  23. {
  24. visRight[v] = true;
  25. if (!link[v] || Hungary(link[v]))
  26. {
  27. link[v] = u;
  28. return true;
  29. }
  30. }
  31. else if(slack > curSlack) slack = curSlack;
  32. }
  33. return false;
  34. }
  35.  
  36. int KM()
  37. {
  38. memset(giveAwayVal, 0, sizeof(giveAwayVal));
  39. memset(link, 0, sizeof(link));
  40. for (int i = 1; i <= N; i++)
  41. curMaxVal[i] = *max_element(gra[i]+1, gra[i]+N+1);
  42.  
  43. for (int i = 1; i <= N; i++)
  44. {
  45. while (true)
  46. {
  47. memset(visLeft, 0, sizeof(visLeft));
  48. memset(visRight, 0, sizeof(visRight));
  49. slack = INT_MAX;
  50. if (Hungary(i)) break;
  51.  
  52. for (int j = 1; j <= N; j++)
  53. {
  54. if (visLeft[j]) curMaxVal[j] -= slack;
  55. if (visRight[j]) giveAwayVal[j] += slack;
  56. }
  57. }
  58. }
  59. int ans = 0;
  60. for (int i = 1; i <= N; i++) ans += gra[link[i]][i];
  61. return ans;
  62. }
  63.  
  64. int main()
  65. {
  66. while(~scanf("%d", &N))
  67. {
  68. for(int i = 1; i <= N; i++)
  69. for(int j = 1; j <= N;j++)
  70. scanf("%d",&gra[i][j]);
  71.  
  72. printf("%d\n",KM());
  73. }
  74. return 0;
  75. }

HDU 2255 奔小康赚大钱 KM算法题解的更多相关文章

  1. hdu 2255 奔小康赚大钱--KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...

  2. hdu 2255奔小康赚大钱 KM算法模板

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹 ...

  3. HDU - 2255 奔小康赚大钱 KM算法 模板题

    HDU - 2255 题意: 分配n所房子给n个家庭,不同家庭对一所房子所需缴纳的钱是不一样的,问你应当怎么分配房子,使得最后收到的钱最多. 思路: KM算法裸题.上模板 #include <i ...

  4. hdu 2255 奔小康赚大钱 KM算法

    看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...

  5. HDU 2255 奔小康赚大钱 KM算法的简单解释

    KM算法一般用来寻找二分图的最优匹配. 步骤: 1.初始化可行标杆 2.对新加入的点用匈牙利算法进行判断 3.若无法加入新编,修改可行标杆 4.重复2.3操作直到找到相等子图的完全匹配. 各步骤简述: ...

  6. hdu 2255 奔小康赚大钱 (KM)

    奔小康赚大钱Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  7. HDU 2255 奔小康赚大钱 KM裸题

    #include <stdio.h> #include <string.h> #define M 310 #define inf 0x3f3f3f3f int n,nx,ny; ...

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

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

  9. HDU 2255 奔小康赚大钱(带权二分图最大匹配)

    HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...

随机推荐

  1. bzoj1231[Usaco2008 Nov]mixup2 混乱的奶牛(状压dp)

    1231: [Usaco2008 Nov]mixup2 混乱的奶牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1032  Solved: 588[ ...

  2. kafka与zookeeper实战笔记

    kafka命令 1.先启动zookeeper zkServer.cmd/zkServer.sh2.启动kafka[需要指定server.properties文件] kafka-server-start ...

  3. Mvc程序字体加载失败问题

    在我们开发的asp.net-mvc项目中,有时会出现字体加载失败的现象,但是一检查字体文件目录,发现文件目录都是存在的且有效的,这是为何呢?原来需要再web.config文件中添价少许配置代码就搞定. ...

  4. Android检测代理

    1. System.getProperties().remove("http.proxyHost"); System.getProperties().remove("ht ...

  5. Java面试概念之String、StringBuffer与StringBuilder的区别

    参考博客 http://www.cnblogs.com/lchzls/p/6711375.html java中String.StringBuffer.StringBuilder是Java编程中经常使用 ...

  6. Asp.net三种事务处理

    事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下三种总结整理如下:方法1:直接写入到sql 中在存储过程中使用 BEGIN TRANS, COMMIT TRANS, ROLLBACK TRA ...

  7. .Net Core添加分布式Session

    一.Session HTTP是一个无状态协议,Web服务器将每一个请求都视为独立请求.并且不保存之前请求中用户的值. Session 状态是ASP.NET Core提供的一个功能,它可以在用户通应用访 ...

  8. JavaScript Array 整理 - 元素操作

    整理一下Array对象中针对元素操作的方法. 分别是: concat (组合数组) join(数组转字符串) pop(删除最后一个元素) shift(删除第一个元素) push(在数组尾部添加新元素) ...

  9. 超简单:纯CSS实现的进度条

    ——————纯CSS实现的进度条—————— HTML: <div class="wrapper"> <div class="bar"> ...

  10. Spring AOP --JDK动态代理方式

    我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinit ...