匈牙利算法的应用场景:二分图

可以理解分为两个集合,集合内部的元素不进行彼此配对,但是两集合之间进行配对

A集合与B集合进行配对,二分图如下

以上即为二分图 ,其中A集合与B集合进行配对,这个图可以刨析为三个部分,A集合为一部分,B集合为一个部分,连接A集合和B集合的线是另一部分,总共这三个部分,如果用代码实现就可以记录这三个部分

连接AB集合的线可以视为对于AB集合的关系

此时带入一个情景

假设你是月老,此时需要对一群男女进行牵红线,但是需要考虑男女之间的意愿,输入的K代表女生所心仪的男生(也就是关系的数量),直到输入0之后停止,M为女生的数量,N代表男生的数量,而你作为月老所需要做的就是尽可能多的对男女进行配对

#include <stdio.h>
bool G[510], B[510], relate[510][510];
//此处的G用来存储女生是否已经有配对的伴侣
//B用来存储男生是否已经被配对
//relate用来记录女生对于男生的心仪情况
//G和B相当于AB集合,而relate就相当于AB之间的关系
int K, M, N;
int main()
{scanf("%d %d %d", &K, &M, &N);int girl = 0, boy = 0;int num = 0;while (K != -1){K--;//表示输入关系的数量,每输入一次就对K进行-1scanf("%d", &girl);if (girl == 0){break;}scanf("%d", &boy);relate[girl][boy] = true;//以女生为行,男生为列,相关关系默认为flase,当输入关系里面有时,更改值成为falseif (G[girl] == false){if (B[boy] == false){//当女生没有伴侣,男生也没有伴侣的时候就可以直接将他俩牵起来//此时需要更改的是男生和女生的配偶状态B[boy] = true;G[girl] = true;num++;//此时算作是已经是配对成功一对,所以num++}else{//如果男生1已经暂定配对了一个伴侣//此时将这个男生1的伴侣先找出来,并检查他的伴侣是否还有其它心仪的男生//如果这个女生1有其他心仪的对象,且这个男生2也没有伴侣//那么就将这个男生2配对给这个女生1,boy所记录男生就可以配给girl记录的女生//如果这个男生1的伴侣没有其他心仪的对象,或者其他心仪对象都有伴侣//那么没有办法配对了,所以num不进行操作for (int i = 1; i <= M; i++){if (relate[i][boy] == true && G[i] == true){for (int k = 1; k <= N; k++){if (relate[i][k] == true && B[k] == false && boy != k){G[girl] = true;B[k] = true;num++;break;}}}}}}}printf("%d", num);
}

粗略的复述一下这个想法

就是G集合和B集合分别表示女生和男生的配偶情况,如果是G或者B有了对象,就让G和B所对应的值改为true,如图所示

而对于实行配对的逻辑就是

而过山车这道题也可以用这种方式进行解决

#include <stdio.h>
#include <string.h>
int map[1000][1000] = {0};
//map记录两个集合之间的关系
int boy[500] = {0};
int flag[500] = {0};
int n, a, b, M, N, num;int fun(int z);int main() {  while (scanf("%d", &n) != EOF && n){num = 0;memset(map, 0, sizeof(map));memset(boy, 0, sizeof(boy));//对两个数组进行初始化,初始化值为0scanf("%d %d", &M, &N);while (n--){scanf("%d %d", &a, &b);map[a][b] = 1;//此处的循环是为了记录所有的关系}for (int i = 1; i <=M; i++){memset(flag, 0, sizeof(flag));//每循环一次,就将flag数组的值重新进行初始化num += fun(i);//这一步就是配对步骤,由fun函数对于关系进行判断//i依旧是代表女生,传入相当于对没一个女生进行配对}printf("%d\n", num);}return 0;
}
int fun(int z) {for (int k = 1; k <= N; k++){//此处的k是在关系网之中的男生if (map[z][k] == 1 && flag[k] ==0)//判断条件为筛选有关系的z,k且k没有被访问过{  flag[k] = 1;//一旦进入该语句,证明k已经被访问过了,所以更改k的值if (boy[k] == 0 || fun(boy[k]) ){boy[k] = z;return 1;} //此处判断语句,分为两种情况//第一种情况:k所对应的男生没有配对对象,这种情况下直接对二者进行配对//第二种情况:k所对应的男生有配对对象,flag已经对此次访问过的对象进行//了标记,所以再次进行调用,对除了目前这个男生的配对对象进行再次配对,//一直到寻找到目标男生,或者找不到为止}}return 0;
}

以上是另一种实现方法,此时用boy这个数组来记录的是与之配对的女生的编号,flag在每一次寻找配对对象的过程中避免多次访问,且在函数进行递归的过程中,能够有效的避免再次访问相同的男生,以找到相应的男生。

匈牙利算法的粗略解释相关推荐

  1. 二分图匹配匈牙利算法DFS实现

    1 /*==================================================*\ 2 | 二分图匹配(匈牙利算法DFS 实现) 3 | INIT: g[][]邻接矩阵; ...

  2. 解题报告:luogu P2423 [HEOI2012]朋友圈【最大团转最大点独立集(匈牙利算法+时间戳优化)】

    图的最大团:"任意两点之间都有一条边相连"的子图被称为无向图的团,点数最多的团为图的最大团 朋友圈中任意两个点之间都有关系,既是图中的团. 答案就是图中的最大团. 我们如果把B国的 ...

  3. 匈牙利算法java实现_匈牙利算法(Hungarian Algorithm)

    匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法.换句话说就是,在可以接受的时间内去做匹配. 1. 描述问题 给定2个集合A和B,然后将AB中的元素完成一个连线.(这不就是小时候的连线题么 ...

  4. edmonds算法matlab,匈牙利算法的matlab实现

    匈牙利算法 算法简介 算法原理 算法实现(附代码) 测试 算法简介 下面摘用百度百科中的解释. 匈牙利算法(Hungarian method)是由匈牙利数学家Edmonds于1965年提出,因而得名. ...

  5. 匈牙利算法——你一定可以看懂的图论算法

    第一次讲解一个算法,也是最近才学到的一个算法,我的语言表达能力可能不是很强,排版也不是特别好,但是真的有认真在做一篇文章,如果有好的意见可以告诉我,非常感谢. 匈牙利算法是一种在多项式时间内求解任务分 ...

  6. 匈牙利算法的python实现

    匈牙利算法是一种组合优化算法,可以在多项式时间内解决分配问题(assignment problem). 该算法由Harold W.Kuhn提出,1955年发表在Naval Research Logis ...

  7. 带你入门多目标跟踪(三)匈牙利算法KM算法

    匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是做多目标跟踪的小伙伴很容易在论文中见到的两种算法.他们都是用来解决多目标跟踪中的数据关联 ...

  8. 匈牙利算法以及在分配问题中的使用

    前部分算法解释引自https://blog.csdn.net/dark_scope/article/details/8880547感谢大神的讲解 [书本上的算法往往讲得非常复杂,我和我的朋友计划用一些 ...

  9. 匈牙利算法(The Hungarian algorithm) :一个通俗易懂的例子

    转自:http://www.hungarianalgorithm.com/examplehungarianalgorithm.php 匈牙利算法:一个例子 我们考虑一个例子,其中四个工作(W1,W2, ...

最新文章

  1. 阅读Book: MultiObjective using Evolutionary Algorithms (2) -- Multi-Objective Optimization: 各种解释多目标
  2. 背包问题教程-01背包,完全背包,多重背包,混合背包 收藏
  3. halcon轮廓擦除_halcon第十二讲,毛刺去除
  4. Android Studio开发基础之Activity之间参数传递
  5. pdol链接mysql_MySQL5.7.11免安装版的安装和配置:解决MYSQL服务无法启动问题
  6. ARM GIC-400 寄存器
  7. AlloyTeam|腾讯全端 AlloyTeam 团队 - HTML5开源图像处理框架AlloyImage
  8. htc服务器更新系统,HTC U11刷机教程_HTC U11卡刷官方ruu升级更新系统
  9. batocera 完整包_Batocera Plus 可能是现如今最强最全最好用的模拟器集成系统!
  10. 六年级计算机应用计划,小学三到六年级信息技术教学计划及进度表.doc
  11. c语言编写克莱姆法则,求克莱姆法则解方程组的c语言代码,能正确运行的
  12. 1198_MISRA_C规范学习笔记_Rule 8.6 Rule 8.7
  13. 【递归入门】走迷宫(c++)
  14. 写给大学男同胞几条择偶建议
  15. 几款炫酷的CSS代码样式
  16. cadence 页间连接符标号的 删除,添加,更新
  17. 昨天苹果发布了2022年平板IPAD10,果然一贯的刀法出众,我在网上找了一个苹果处理器历代的发布产品对比
  18. etal中间有空格吗_科学网—英文论文中i.e.,e.g.,etc.,viz.的简要小结 - 贾琼的博文...
  19. 解决谷歌浏览器升级后,selenium无法使用的问题
  20. 松下FP-XHC60T 标准中型程序,程序用于3C点胶设备,总共逻辑5千多步,含昆仑通态触摸屏程序

热门文章

  1. 附录:15个创新世界119座城整体规划与核心思想
  2. 模拟仪器仪表ActiveX(OCX)控件 - 实时曲线(RTChart)介绍及下载地址
  3. 链塔智库联合赛迪区块链发布中国区块链百强榜
  4. OFDMA/SC-FDMA原理及在5G中应用
  5. DS1307实时时钟RTC读取(STM32)记录
  6. STM32F0项目进阶之实时时钟DS1307
  7. 世界人口你未必知道的事实
  8. 动漫制作:MMD软体制作《1》
  9. Python requests +PrettyTable 查询高铁或者动车票
  10. Axure RP 9交互原型设计软件增加了哪些新功能