二分图匹配问题之km算法代码
下列代码是二分图的最佳匹配问题,即权值最大的匹配,网上找了一些代码,有些小问题,修改了下,下面这份代码是修改后的:
#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算法代码相关推荐
- 二分图(三)——KM算法
写完这一章,大概二分图的匹配问题也该完结了吧. 其实我自己现在对KM算法也是刚刚理解,有理解不到位之处还请大家指出. KM算法:求在一个二分图的完备匹配中的最大权值匹配的算法.(下文简称为最佳完备匹配 ...
- 洛谷P3386:网络流之二分图匹配,最大流算法
二分图:我的理解是,对图中的点集,可分为两个集合U和V,使得两个集合之间存在通路,且集合内部不存在通路.如上图. 匹配:两两不含公共端点的边集合M 最大匹配:边数最多的匹配 完美匹配:最大匹配的匹配数 ...
- BZOJ1433 ZJOI2009 假期的宿舍 二分图匹配
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2375 Solved: 1005 [Submit][S ...
- 奔小康赚大钱 HDU - 2255( 二分图匹配KM算法详解)
题目 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百 ...
- 二分图最大权匹配问题KM算法讲解 HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...
- KM算法解决二分图最大权分配问题
匈牙利算法和KM算法都可用来解决任务分配问题(亦称指派问题):假设有n名员工以及n份工作,一个人只能完成一项任务且能完成的任务各不相同.问如何安排员工才能使效率达到最大. 用大白话来描述二分图:二分图 ...
- 算法模板——二分图匹配
实现功能为二分图匹配 原理:匈牙利算法,核心思想--匹配上了就配,没直接匹配上也要通过前面的腾出位置让这个匹配上(详见:趣写算法系列之--匈牙利算法) 本程序以Codevs2776为例 详见Codev ...
- 【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 ...
- 匈牙利算法解决二分图匹配问题
匈牙利算法是由匈牙利数学家Edmonds于1965年提出.匈牙利算法是基于Hall定理中充分性证明的思想,它是二分图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的 ...
最新文章
- ext中给文本框赋值的方法_大多数人不知道的Python合并字典的七种方法
- 解决:MVC对象转json包含\r \n
- redis相关知识记录整理
- python画图表的库_「Python」python绘制图表
- 大小端、位段和内存对齐
- Java:伪造工厂的闭包以创建域对象
- ajax 请求svg,jQuery append 到AJAX加载的SVG问题
- plsql初始错误sql.net未正确安装_ANSYS | ansys18.0完整安装过程及常见问题解决方案[图文]...
- 力扣——搜索插入位置
- 【物理应用】基于matlab波数谱计算【含Matlab源码 508期】
- 端口扫描工具Namp
- 西门子二代精简屏如何使用U盘下载触摸屏程序
- Python学习——语法错误与异常
- mysql 经典错误解决方案 :Incorrect string value ‘xE6x95x85xE4xBAx8B...‘ for column
- 摄像头 SONY VISCA 协议
- win10锁屏壁纸路径
- 如何用C语言实现小游戏——扫雷
- OGNL学习笔记-OGNL基础
- Unity游戏制作(五)
- python生成矩阵 元素随机_用python生成随机矩阵
热门文章
- 在管家婆软件中项目管理教程
- Protel 99se汉化步骤
- 自动量程万用表的实现原理_电子元器件用指针万用表、数字万用表、自动量程万用表测量原理图解大全教会您怎么看与测的呢?...
- Django报错:'Specifying a namespace in include() without providing an app_name '
- 汇编大作业(课程设计):简易英英词典
- [转][darkbaby]任天堂传——失落的泰坦王朝(下)
- 单相全桥逆变器带负载电流前馈的双闭环控制系统设计及仿真
- 关于PC套件显示红外连接出现问题而导致连接不上的解决方案(zz)
- 面试感悟----一名3年工作经验的程序员应该具备的技能
- Unity 3D AI鸟群算法 AI鱼群算法