下列代码是二分图的最佳匹配问题,即权值最大的匹配,网上找了一些代码,有些小问题,修改了下,下面这份代码是修改后的:

#include<algorithm>using namespace std;
const int MAXN = 305;
const int INF = 0x3f3f3f3f;int disMat[MAXN][MAXN]; //特征矩阵
int ex_a[MAXN]; //a的期望
int ex_b[MAXN]; //b的期望
bool vis_a[MAXN]; //记录每一轮匹配过的a
bool vis_b[MAXN]; //记录每一轮匹配过的b
int match[MAXN]; //记录每个b匹配到的a 如果没有则为-1
int slack[MAXN]; //记录每个b如果能被a匹配到最少还需要多少期望值int aN, bN;bool dfs(int a)
{vis_a[a] = true;for (int b = 0; b < bN; ++b){if (vis_b[b])// 每一轮匹配 每个b只尝试一次continue;int gap = ex_a[a] + ex_b[b] - disMat[a][b];if (gap == 0) //如果符合要求{vis_b[b] = true;if (match[b] == -1 || dfs(match[b])) // 找到一个没有匹配的b 或者该b的a可以找到其他a{match[b] = a;return true;}}else{slack[b] = min(slack[b], gap); /// slack 该b要得到一个a的匹配 还需多少期望值}}return false;
}int KM()
{int bNori = bN;//特征矩阵对于bN<aN的情况缺值补0 因为所有a一定需要匹配一个b 不然跳不出循环if (bN < aN){for (int j = bN; j < aN; ++j){for (int i = 0; i < aN; ++i){disMat[i][j] = 0;}}bN = aN;}memset(match, -1, sizeof(match)); // 初始每个b都没有匹配的a memset的单位是char 但是对于非char型 仅对-1和0的赋值有效 这属于魔术编程 不清楚的话最好别这么用memset(ex_b, 0, sizeof(ex_b)); //初始每个b的期望值为0// 每个a的初始期望值是与它有匹配关系的b的最大的特征值for (int i = 0; i < aN; ++i){ex_a[i] = disMat[i][0];for (int j = 1; j < bN; ++j){ex_a[i] = max(ex_a[i], disMat[i][j]);}}// 尝试为每一个a做匹配for (int i = 0; i < aN; ++i){// 因为要取最小值 初始化为无穷大// tips: 这里的slack要赋的值不是0或-1 所以不能再用memset赋了 要写for循环for (int j = 0; j < MAXN; ++j){slack[j] = INF;}// 为每个a解决匹配的方法是 :如果找不到就降低期望值 直到找到或者期望值降到0为止while (1){// 记录每轮匹配中a和b是否被尝试匹配过memset(vis_a, false, sizeof vis_a);memset(vis_b, false, sizeof vis_b);if (dfs(i)) // 找到匹配 退出break;// 如果不能找到 就降低期望值// 最小可降低的期望值int d = INF;for (int j = 0; j < bN; ++j){if (!vis_b[j])d = min(d, slack[j]);}for (int j = 0; j < aN; ++j){// 所有访问过的a降低期望值if (vis_a[j])ex_a[j] -= d;}for (int j = 0; j < bN; ++j){// 所有访问过的b增加期望值if (vis_b[j])ex_b[j] += d;// 没有访问过的b 降低a的期望值elseslack[j] -= d;}}}// 匹配完成 查看匹配int res = 0;for (int j = 0; j < bNori; ++j){int aIdx = match[j];int bIdx = j;if (disMat[aIdx][bIdx] > 0){printf("a: %d b: %d\n", aIdx, bIdx);res += disMat[aIdx][j];}}return res;
}int main()
{aN = 4;bN = 3;disMat[0][0] = 3;disMat[0][1] = 0;disMat[1][1] = 2;disMat[2][0] = 4;int res = KM();printf("total wei: %d\n",res);return 0;
}

二分图匹配问题之km算法代码相关推荐

  1. 二分图(三)——KM算法

    写完这一章,大概二分图的匹配问题也该完结了吧. 其实我自己现在对KM算法也是刚刚理解,有理解不到位之处还请大家指出. KM算法:求在一个二分图的完备匹配中的最大权值匹配的算法.(下文简称为最佳完备匹配 ...

  2. 洛谷P3386:网络流之二分图匹配,最大流算法

    二分图:我的理解是,对图中的点集,可分为两个集合U和V,使得两个集合之间存在通路,且集合内部不存在通路.如上图. 匹配:两两不含公共端点的边集合M 最大匹配:边数最多的匹配 完美匹配:最大匹配的匹配数 ...

  3. BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配

    1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2375  Solved: 1005 [Submit][S ...

  4. 奔小康赚大钱 HDU - 2255( 二分图匹配KM算法详解)

    题目 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.  这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百 ...

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

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

  6. 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)

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

  7. KM算法解决二分图最大权分配问题

    匈牙利算法和KM算法都可用来解决任务分配问题(亦称指派问题):假设有n名员工以及n份工作,一个人只能完成一项任务且能完成的任务各不相同.问如何安排员工才能使效率达到最大. 用大白话来描述二分图:二分图 ...

  8. 算法模板——二分图匹配

    实现功能为二分图匹配 原理:匈牙利算法,核心思想--匹配上了就配,没直接匹配上也要通过前面的腾出位置让这个匹配上(详见:趣写算法系列之--匈牙利算法) 本程序以Codevs2776为例 详见Codev ...

  9. 【HDU - 5090】Game with Pearls (匈牙利算法,二分图匹配)

    题干: Tom and Jerry are playing a game with tubes and pearls. The rule of the game is: 1) Tom and Jerr ...

  10. 匈牙利算法解决二分图匹配问题

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出.匈牙利算法是基于Hall定理中充分性证明的思想,它是二分图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的 ...

最新文章

  1. ext中给文本框赋值的方法_大多数人不知道的Python合并字典的七种方法
  2. 解决:MVC对象转json包含\r \n
  3. redis相关知识记录整理
  4. python画图表的库_「Python」python绘制图表
  5. 大小端、位段和内存对齐
  6. Java:伪造工厂的闭包以创建域对象
  7. ajax 请求svg,jQuery append 到AJAX加载的SVG问题
  8. plsql初始错误sql.net未正确安装_ANSYS | ansys18.0完整安装过程及常见问题解决方案[图文]...
  9. 力扣——搜索插入位置
  10. 【物理应用】基于matlab波数谱计算【含Matlab源码 508期】
  11. 端口扫描工具Namp
  12. 西门子二代精简屏如何使用U盘下载触摸屏程序
  13. Python学习——语法错误与异常
  14. mysql 经典错误解决方案 :Incorrect string value ‘xE6x95x85xE4xBAx8B...‘ for column
  15. 摄像头 SONY VISCA 协议
  16. win10锁屏壁纸路径
  17. 如何用C语言实现小游戏——扫雷
  18. OGNL学习笔记-OGNL基础
  19. Unity游戏制作(五)
  20. python生成矩阵 元素随机_用python生成随机矩阵

热门文章

  1. 在管家婆软件中项目管理教程
  2. Protel 99se汉化步骤
  3. 自动量程万用表的实现原理_电子元器件用指针万用表、数字万用表、自动量程万用表测量原理图解大全教会您怎么看与测的呢?...
  4. Django报错:'Specifying a namespace in include() without providing an app_name '
  5. 汇编大作业(课程设计):简易英英词典
  6. [转][darkbaby]任天堂传——失落的泰坦王朝(下)
  7. 单相全桥逆变器带负载电流前馈的双闭环控制系统设计及仿真
  8. 关于PC套件显示红外连接出现问题而导致连接不上的解决方案(zz)
  9. 面试感悟----一名3年工作经验的程序员应该具备的技能
  10. Unity 3D AI鸟群算法 AI鱼群算法