二分图匹配详解

二分图的原始模型及相关概念

二分图又称作二部图,是图论中的一种特殊模型。

设G=(V,E)G=(V,E)是一个无向图。

如顶点集V可分割为两个互不相交的子集(A, B),并且图中每条边(i,j)所关联的两个顶点 i 和 j 就都分属两个不同的子集。则称图G为二分图,因此将上边顶点集合称为X 集合,下边顶点结合称为Y集合,如下图,就是一个二分图。

给定一个二分图G(无向图),在G的一个子图M中,M图中的任意两条边都不依附于同一个顶点,则称M是一个匹配.

选择这样的边数最大的子集称为图的最大匹配问题

如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。

增广路(交错路):路径的起点和终点都是还没有匹配过的点,并且路径经过的连线是一条没被匹配,一条已经匹配过,再下一条又没有匹配这样交替的出现。找到这样的路径过后,显然路径里没有被匹配的连线比已经匹配了的连线多一条,于是修改匹配图,把路径里所有匹配过的连线去掉匹配关系,把没有匹配的连线变成匹配的,这样匹配数就比原来多1个。

求解二分图最大匹配

匈牙利算法

匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

-------等等,看得头大?那么请看下面的版本:

通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在让我们无视掉所有的单相思,你拥有的大概就是下面这样一张关系图,每一条连线都表示互有好感。

本着救人一命,胜造七级浮屠的原则,你想要尽可能地撮合更多的情侣(也就是二分图最大匹配数),匈牙利算法的工作模式会教你这样做:

1. 先试着给1号男生找妹子,发现第一个和他相连的1号女生还名花无主,那就连上一条蓝线

2.接着给2号男生找妹子,发现第一个和他相连的2号女生名花无主,也连上蓝线

3.接下来轮到3号男生了,很遗憾1号女生已经有主了,怎么办呢?

我们试着给之前1号女生匹配的男生(也就是1号男生)另外分配一个妹子。

(黄色表示这条边被临时拆掉)

与1号男生相连的第二个女生是2号女生,但是2号女生也有主了,怎么办呢?我们再试着给2号女生的原配,重新找个妹子(注意这个步骤和上面是一样的,这是一个递归的过程)

此时发现2号男生还能找到3号女生,那么之前的问题迎刃而解了,回溯回去

2号男生可以找3号妹

 1号男生可以找2号妹子了

 3号男生可以找1号妹子

所以第三步最后的结果就是:

4.接下来是4号男生,很遗憾,按照第三步的节奏我们没法给4号男生腾出来一个妹子,我们实在是无能为力了

这就是匈牙利算法的流程,其中找妹子是个递归的过程,最最关键的字就是“ 腾”字

其原则大概是:有机会上,没机会创造机会也要上

代码:


bool find(int x){int i,j;for (j=1;j<=m;j++){    //扫描每个妹子if (line[x][j]==true && used[j]==false)//uesd数组表示第i个女生在这次找增广路当中,是否被查看过。//如果有暧昧并且还没有标记过(这里标记的意思是这次查找曾试图改变过该妹子的归属问题,但是没有成功,所以就不用瞎费工夫了){used[j]=1;if (girl[j]==0 || find(girl[j])) { //link数组表示第 j 个女生匹配的男生//名花无主或者能腾出个位置来,这里使用递归girl[j]=x;return true;}}}return false;}

在主程序我们这样做:每一步相当于我们上面描述的一二三四中的一步

for (i=1;i<=n;i++)
{memset(used,0,sizeof(used));    //这个在每一步中清空if find(i) all+=1;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/701695.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

定时任务处理-Spring Task

目录 1 前言 2 cron表达式 2.1 相关概念的介绍 2.2 举个例子(白雪警告) 2.3 使用网站自动生成 3 Spring Task的使用 3.1 导入依赖坐标 3.2 开启任务调度 3.3 自定义定时任务类 1 前言 当我们需要处理一些定时任务的时候就需要用到我们的Spring Task&#xff0c;接下来…

(done) 两个矩阵 “相似” 是什么意思?

参考视频&#xff1a;https://www.bilibili.com/video/BV1zu411673J/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 参考资料&#xff1a;https://baike.baidu.com/item/%E7%9B%B8%E4%BC%BC%E7%9F%A9%E9%98%B5/10369874?frge_a…

算能RISC-V通用云编译飞桨paddlepaddle@openKylin留档

尝试一在riscv里编译飞桨。 先总结&#xff1a; 下载飞桨代码&#xff0c;参照pr修改代码 然后编译 cmake ../ -DWITH_GPUOFF -DWITH_RISCVON make -j 16 TARGETRISCV64_GENERIC 编译好后安装&#xff1a; pip install paddlepaddle-0.0.0-cp38-cp38-linux_riscv64.whl -…

Opencv(C++)学习 ARM上引用opencv报相关头文件找不到

简单问题记录&#xff0c;C 与C互相引用时应该多注意类似问题。 问题描述&#xff1a;在项目中&#xff0c;建立了一个interface.h提供了一个C语言兼容的接口void work()&#xff0c;并在对应的interface.cpp中使用OpenCV完成相关处理实现。在PC端测试时&#xff0c;main.cpp成…

【HTML/CSS/JavaScript-编程指南】

HTML/CSS/JavaScript-编程指南 ■ HTML/CSS/JavaScript简介■ HTML/CSS/JavaScript学习网站■ VScode■ VSCode编写HTML■ VSCode编写CSS■ VSCode编写JavaScript ■ 语法■ HTML语法■ CSS语法■ JavaScript 语法 ■ HTML/CSS/JavaScript简介 HTML&#xff08;全称 Hypertext…

小波变换模拟

小波变换是一种信号处理技术&#xff0c;通过在时间-频率域中使用基于小波的函数进行信号分析。小波变换在处理非平稳信号和图像时特别有用&#xff0c;可以将信号分解为不同频率的成分。它在数据压缩、去噪、特征提取等领域有广泛应用。 MATLAB中提供了用于二维离散小波变换的…

css4浮动+清除浮动

浮动 一.常见网页布局1.三种布局方式2.布局准则 二.浮动&#xff08;float&#xff09;1.好处2.概念3.三大特性4.使用5.常见网页布局模板6.注意点 三.清除浮动1.why2.本质3.语法4.四种way&#xff08;后三个都是给父级添加&#xff09;清除浮动总结 一.常见网页布局 1.三种布局…

终端启动jupyter notebook更换端口

一、问题描述 如果尝试在端口 8889 上启动 Jupyter Notebook 但最终启动在了 8890 端口&#xff0c;这通常意味着 8889 端口已经被占用。要解决这个问题&#xff0c;可以尝试以下几种方法来关闭占用 8889 端口的进程。 1. 查找并终止占用端口的进程 首先&#xff0c;需要找出…

课时45:表达式_表达式_字符串表达式

3.2.3 字符串表达式 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 简介 所谓的字符串表达式&#xff0c;主要是判断 比较运算符 两侧的值的内容是否一致&#xff0c;由于bash属于弱类型语言&#xff0c;所以&#xff0c;默认情况…

【课程作业】提取图中苹果的面积、周长和最小外接矩形的python、matlab和c++代码

提取图中苹果的面积、周长和最小外接矩形 在图像处理中&#xff0c;提取对象的关键属性是常见的任务之一。本文将演示如何使用三种流行的编程语言——Python、Matlab和C&#xff0c;利用相应的图像处理库&#xff08;OpenCV或Matlab内置函数&#xff09;来提取图像中苹果的面积…

Java8 Stream API 详解:流式编程进行数据处理

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&…

切比雪夫(最小区域法)平面拟合算法

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 本期话题&#xff1a;切比雪夫&#xff08;最小区域法&#xff09;平面拟合算法 相关背景和理论 点击前往 主要介绍了应用背景和如何转化成线性规划问题 平拟合输入和…

Vue2:多级路由案例

一、情景说明 上一节&#xff0c;我们学习了Vue中的路由功能 但是&#xff0c;只是基础的一级路由 在实际生产中&#xff0c;路径不可能只有一级&#xff0c;一般都有3,4层级 二、案例 1、修改路由器文件 index.js 新增两个组件 这里实现二级路由配置 关键配置&#xff1a;…

命题逻辑|析取、合取和蕴含到底什么意思

如是我闻&#xff1a;在逻辑学中&#xff0c;“析取”、“合取”和“蕴含”这些术语的中文翻译是有其逻辑和哲学基础的&#xff0c;它们准确地反映了这些逻辑操作的本质。虽然他们被翻译的很高级&#xff0c;但并不能让人一下子就明白。 析取 (Disjunction) 原理&#xff1a;…

【C++精简版回顾】8.const

1.const数据成员 &#xff08;1&#xff09;const数据成员必须使用初始化参数列表 &#xff08;2&#xff09;不能修改 &#xff08;3&#xff09;不能修改必须初始化 class MM { public:MM() {}MM(int age, string name) :age(age), name(name) {}~MM() {cout << "…

SpringBoot和ApiFox整合快速上手

前置&#xff1a;IDEA版本IntelliJ IDEA 2023.2.4&#xff0c;Apifox 2.5.6 安装插件&#xff1a;Apifox Helper1.2.1 目录 1.文档生成 2.提取登录接口token 1.文档生成 把密钥配置到 导入成功:文档就会出现 2.提取登录接口token 之后我们再使用的时候&#xff0c;只需要配置…

面试整理(昆明)去面试就更新

1.MyBatis与MyBatis-Plus的区别&#xff1f; MyBatis和MyBatis-Plus都是Java语言中非常常用的ORM框架&#xff0c;二者有以下区别&#xff1a; 1.实现方式不同 MyBatis是基于XML或注解方式进行数据库操作的持久化框架&#xff0c;它提供了简单的CRUD操作及动态SQL生成等功能。…

五个使用Delphi语言进行开发的案例

案例一&#xff1a;学生信息管理系统 某学校需要开发一个学生信息管理系统&#xff0c;用于记录学生的基本信息、成绩和考勤情况等。开发者使用Delphi语言进行开发&#xff0c;设计了一个包含多个窗体的应用程序。主窗体用于展示学生的列表和基本信息&#xff0c;其他窗体则用…

2024.2.25 -ElasticSearch 进阶

倒排索引 Elasticsearch的倒排索引机制是通过将文档中出现的词汇与它们所在的文档ID关联起来&#xff0c;实现快速查找包含特定词汇的文档。下面是一个具体的例子来说明倒排索引的工作原理&#xff1a; 假设我们有一个简单的文章集合&#xff0c;包含以下三篇文章&#xff1a…

Java学习——泛型

Java泛型是Java语言中的一个特性&#xff0c;它允许你在类、接口和方法上定义类型参数。使用泛型可以使代码更加通用&#xff0c;减少代码重复&#xff0c;并在编译时提供更强的类型检查。下面分别介绍泛型类、泛型方法和泛型接口。 泛型类 泛型类是在类名后添加类型参数声明…