二分图最大匹配-匈牙利算法

article/2025/9/17 9:38:33

      今天介绍 匈牙利算法 : 匈牙利算法,是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,由匈牙利数学家Edmonds于1965年提出,因而得名。

      先介绍一下增广路径:若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。文字难以理解,看图:

      首先 假设 图G中已经两两匹配了4个点 即 M 中 又 (1,A)(4,C)两条边;

      然后路径p是一条连接未匹配点2和D的一条路径 其中属于M的边和不属于M的边交错:(2-A-1-C-4-D),这样就称p为M的一条增广路径;

       增广路径的性质:

               1-P的路径长度必定为奇数,第一条边和最后一条边都不属于M。

               2-不断寻找增广路可以得到一个更大的匹配M’,直到找不到更多的增广路。

               3-M为G的最大匹配当且仅当不存在M的增广路径。

               4-最大匹配数M+最大独立数N=总的结点数。

      我们将P中不属于M的路径加入M,将原来属于M的路径去除。M的匹配数增加到了 3,如果我们一只找M的增广路径然后取反,直到M没有增广路,这时我们就找到了M的最大匹配数,这也时 匈牙利算法的核心所在;

      匈牙利算法 :首先向M中增加一条路径,然后一只寻找M的增广路径直到M中不存在增广路径为止,这时我们就完成了最大匹配的寻找。

      用一个问题来展现匈牙利算法:

      假设有一群人生了不同的病(一个人只能生一种病),这里有多种可以治病的药丸,并且一种药丸只能治一种病且仅有一个,问最多能救治多少人;

      输入 :在第一行中给出 n ,m, k 其中 n是人数,m 是 药的种类数,k是 人和药共有多少种匹配,然后 跟着 k 行,每行 一个 整数:人的标号,一个字符 :药的种类。

      输出:在一行中输出最多可以救治多少人。

      代码:

//二分图最大匹配-匈牙利算法
#include<stdio.h>
#include<string.h>
#define MAXN 100       //定义最大人数
#define TYPE 6        //定义药的种类数 
int map[MAXN][MAXN]; //用来储存人和药的关系  
int vis[MAXN];      //用来标记药的被使用人
int used[MAXN];	   //用在递归的时候标记修改的药的种类 
char array[6] = {'a','b','c','d','e','f'};
int GetPos(char x){ //获取药的索引 int i, position;for (i=0;i<TYPE;i++){if (array[i] == x)return i; // 找到的话就返回索引 }return -1; // 找不到就返回-1 
}
void init(){ // 初始化函数 memset(map,-1,sizeof(map));memset(vis,-1,sizeof(vis));memset(used,-1,sizeof(used));
}
int MaxMatch(int n){ // n是人的代号 int i;for (i=0;i<TYPE;i++){if ( used[i]==-1 && map[n][i]==1) //寻找增广路 {used[i] = 1;   if (vis[i] == -1||MaxMatch(vis[i])==1){vis[i] = n;return 1;}}}return -1;
}
int main (){int n, m, i, k, cnt = 0, b, index;//n是患病的人数,m是药的种类数,i是循环变量,k是人和药对应关系的数量,cnt记录最大匹配数,b是某人的代号,index记录药的位置 char a; //a是药的品种 scanf("%d%d%d",&n,&m,&k);init();for (i=0;i<k;i++){scanf("%d %c",&b,&a);index = GetPos(a);map[b][index] = 1;}for (i=1;i<=n;i++){memset(used,-1,sizeof(used));//每次都要初始化一遍 每次寻找增广路都与之前无关 if (MaxMatch(i)==1)cnt++;}printf("%d\n",cnt);
}

 


http://chatgpt.dhexx.cn/article/obuX8m08.shtml

相关文章

求解分配问题(二) 二分图最大匹配算法

我的前一篇文章介绍了对于分配问题的Kuhn-Munkre算法&#xff0c;该算法其实可以看作是邻接矩阵形式的匈牙利算法&#xff0c;如果更抽象地看这个算法&#xff0c;它可以看成是一个二分图匹配算法的变体算法&#xff0c;具体的说&#xff0c;是二分图最大权重匹配算法。我打算也…

二分图最大匹配(匈牙利算法,Dinic网络流算法)

二分图最大匹配 二分图最大匹配问题: 有两个集合A,B,两个集合间有多条边连接集合中的点,且单个集合中的点各不相连,求两集合的点能两两配对的最大匹配数. (参考:)二分图最大匹配——匈牙利算法 匈牙利算法: A集合记录各点与B集合相连的点,B集合记录某点与A集合中匹配的点.遍历…

二分图最大匹配与最大独立集

一.概念部分 1.什么是二分图&#xff1f; 通俗的说法&#xff1a;就是可以把图分成两部分&#xff0c;每一部分任意两点之间没有关系&#xff08;同一部落&#xff09;&#xff0c;两部分之间点可能存在多种关系。 2.怎么判断二分图&#xff1f; &#xff08;1&#xff09;…

二分图最大匹配及最大权匹配

二分图最大匹配学习 一.二分图的基本知识二.二分图最大匹配什么是二分图最大匹配怎么求二分图最大匹配 三.二分图最大权匹配四.例题训练三.最小点覆盖数 一位大佬的神级解释 本以为有了网络流&#xff0c;就不用再学匈牙利了&#xff0c;但在做题的过程中&#xff0c;发现有些…

二分图最大匹配问题(匈牙利算法)

什么是二分图 如果一个无向图的的顶点可以分为两个互不相交的子集A和B&#xff0c;那么它就是二分图。也就是说&#xff0c;A、B内部不存在连边&#xff0c;所有连边都一头连着A中的顶点&#xff0c;另一头连着B中的顶点。 什么是二分图最大匹配&#xff1f; 二分图最大匹配…

二分图 二分图最大匹配

首先来说一下什么是二分图。 二分图 二分图又称作二部图&#xff0c;是图论中的一种特殊模型。 设G(V, E)是一个无向图。如果顶点集V可分割为两个互不相交的子集X和Y&#xff0c;并且图中每条边连接的两个顶点一个在X中&#xff0c;另一个在Y中&#xff0c;则称图G为二分图。…

二分图最大匹配(最大流)

先举个例子&#xff0c;有N台计算机和K个任务&#xff0c;每个计算机只能执行一个任务&#xff0c;但可以执行多种任务。现在给出N和K&#xff0c;和其关系&#xff0c;求出最多能处理的任务数。 这就是典型的二分图&#xff0c;整张图被分为两半&#xff0c;一半是电脑&#…

图论总结(一)二分图最大匹配

二分图最大匹配 (一)、二分图 1、定义2、性质3、判定(二)、二分图的匹配 1、二分图的最大匹配2、 Knig定理及其证明3、最小边覆盖与最大独立集(三)、增广路径 1、定义2、性质3、寻找增广路(四)、匈牙利算法 1、找增广路经的算法2、实践3、算法分析(五)、例题 1、最小…

二分图的最大匹配

一、概念&#xff1a; 二分图&#xff1a;简单来说&#xff0c;如果图中点可以被分为两组&#xff0c;并且使得所有边都跨越组的边界&#xff0c;则这就是一个二分图。准确地说&#xff1a;把一个图的顶点划分为两个不相交集 U 和V &#xff0c;使得每一条边都分别连接U、V中的…

二分图最大匹配问题

最近在做的打车项目中&#xff0c;涉及到了用户叫单后&#xff0c;将所有出单司机和所有订单匹配的问题&#xff0c;借此来学习一下二分图的匹配算法。 一、无权二分图最大匹配 首先要区分一下各个概念&#xff1a; 匹配&#xff1a;图G的一个匹配是由一组没有公共端点的不是…

二分图最大匹配——匈牙利算法

二分图最大匹配 &#xff08;一&#xff09;、二分图的介绍1、定义2、充要条件 &#xff08;二&#xff09;、二分图的匹配1、二分图的最大匹配2、增广路径3、匈牙利算法&#xff08;1&#xff09;、复杂度&#xff08;2&#xff09;、算法思路&#xff08;3&#xff09;、代码…

B树最小高度和最大高度的推导

B树最小高度和最大高度的推导 对任意一棵包含n个关键字&#xff0c;高度为h&#xff0c;阶数为m的B树&#xff0c;其最小高度和最大高度的推导过程如下&#xff1a;

算法篇:树之树的高度

算法&#xff1a; 这一类题目很简单&#xff0c;不过却是树的最基本操作之一&#xff0c;引申为判断树是不是平衡二叉树。 一般做法是&#xff0c;计算二叉树的左右子树的高度1&#xff0c;然后取它们的最大值或者最小值。 题目1: https://leetcode-cn.com/problems/balanced-b…

【二叉树】最小高度树

0x00 题目 给定一个 有序 整数数组 元素各不相同且按 升序 排列 编写一个算法&#xff0c;创建一棵 高度最小 的二叉 搜索 树 给定有序数组: [-10,-3,0,5,9] 一个可能的答案是&#xff1a;[0,-3,9,-10,null,5] 它可以表示下面这个高度平衡二叉搜索树&#xff1a; 0 / \ -3 …

常见数据结构详细图解、树的高度、深度、层数、跳表、二叉搜索树、平衡二叉树、红黑树、B树、B+树

常见数据结构 常用的数据结构知识。 1.1 跳表 上图是一个有序链表&#xff0c;我们要检索一个数据就挨个遍历。如果想要再提升查询效率&#xff0c;可以变种为以下结构&#xff1a; 现在&#xff0c;我们要查询11&#xff0c;可以跳着来查询&#xff0c;从而加快查询速度。 …

树的高度 递归法和非递归法

递归法思路&#xff1a; 树的高度即节点子树的高度1&#xff08;节点子树的高度即左子树高度&#xff0c;右子树高度的最大值&#xff09; 代码如下&#xff1a; // Height_Recursive 递归法求树的高度 int Height_Recursive(TreeNode* pTree) {if (pTree NULL) {return 0;…

获取树高度的两种方法与完全二叉树的判断

树的高度 树的高度是节点高度的最大值。 每一层节点的高度如图所示。 方法一&#xff1a;递归 根节点的高度显然就是二叉树的高度。 /** * 获取树的高度* return*/ public int height(){return height2(root); }/*** 使用递归方法获取树的高度* param node* return*/ priv…

红黑树

一.简介 红黑树作为一种二叉搜索树的一种实现&#xff0c;红黑树的左右子树高度差可能大于 1。所以红黑树不是严格意义上的平衡二叉树&#xff08;AVL&#xff09;&#xff0c;但红黑树是黑色节点完美平衡&#xff0c; 其平均统计性能要强于 AVL 。 红黑树是每个节点都带有颜…

B树最大高度推导

文章目录 B树最大高度推导推导B树的最小高度推导最大高度 B树&#xff1a;MySQL数据库索引是如何实现的&#xff1f;1. 遇到问题2. 尝试用学过的数据结构解决这个问题3. 改造二叉查找树4. 索引的弊端 B树最大高度推导 【声明几个重要概念】 B树的关键字就是要查找的东西 B树…

红黑树详解

1&#xff0c;红黑树特点 每一个结点都有颜色&#xff0c;要么红色&#xff0c;要么黑色。根结点必须是黑色的。红色结点的子结点必须是黑色的。任何一个结点&#xff0c;到它所有叶子结点&#xff0c;经过相同个数的黑色结点。&#xff08;红黑树的平衡含义&#xff0c;左右高…