
二部图中的匹配是一组边的选择方式,使两条边不共享一个端点。最大匹配是最大大小(最大边数)的匹配。在最大匹配中,如果向其添加任何边,则该边不再是匹配。对于给定的二部图,可以有多个最大匹配。
我们为什么在乎?
现实世界中有许多问题可以形成为二部匹配。例如,考虑以下问题:
“共有M个求职者和N个职位。每个求职者都有一部分他/她感兴趣的职位。每个职位空缺只能接受一个求职者,而一个求职者只能被任命一个职位。在中为求职者分配职位,以便尽可能多的求职者获得工作。”

我们强烈建议您先阅读以下帖子。“最大流问题的Ford-Fulkerson算法”
最大二部匹配和最大流问题:
最大二部匹配(MBP)问题可以通过将其转换为流网络来解决(请参阅此视频了解我们是如何得出此结论的)。以下是步骤。
最大匹配2
1) 构建流网络:流网络中必须有源和汇。因此,我们向所有申请者添加一个源,并从源添加边。类似地,将所有作业的边添加到接收器。每条边的容量标记为1个单位。
最大匹配2
2) 查找最大流量:我们使用Ford Fulkerson算法在步骤1中构建的流量网络中查找最大流量。最大流量实际上是我们正在寻找的MBP。
如何实施上述方法?
让我们首先定义输入和输出表单。输入采用Edmonds矩阵的形式,该矩阵是一个2D数组“bpGraph[M][N]”,其中有M行(针对M个求职者)和N列(针对N个工作)。如果第i个申请人对第j个工作感兴趣,则bpGraph[i][j]的值为1,否则为0。
输出是能找到工作的最大人数。
实现这一点的一种简单方法是创建一个矩阵,该矩阵表示具有M+N+2个顶点的有向图的邻接矩阵表示。为矩阵调用fordFulkerson()。此实现需要O((M+N)*(M+N))额外空间。
利用图是二部图且每条边的容量为0或1的事实,可以减少额外空间并简化代码。其想法是使用DFS遍历为申请人找到一份工作(类似于福特·富尔克森(FordFulkerson)中的扩充路径)。我们为每个申请者调用bpm(),bpm()是一个基于DFS的函数,它尝试所有可能的方法来为申请者分配工作。
在bpm()中,我们会一个接一个地尝试申请人“u”感兴趣的所有工作,直到我们找到一份工作,或者所有工作都是在运气不佳的情况下尝试的。对于我们尝试的每一项工作,我们都会遵循以下原则。
如果工作没有分配给任何人,我们只需将其分配给申请人并返回true。如果一个作业分配给了其他人,比如x,那么我们递归地检查x是否可以分配给其他作业。为了确保x不再获得相同的工作,我们在递归调用x之前将作业标记为“v”。如果x可以获得其他作业,我们将更改作业“v”的申请人并返回true。我们使用一个数组maxR[0..N-1],它存储分配给不同工作的申请者。
如果bmp()返回true,则表示流网络中有一个扩充路径,并且在maxBPM()中的结果中添加了1个流单元。

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;namespace Legalsoft.Truffer.Algorithm
{public static partial class Algorithm_Gallery{private static bool Maximum_Bipartite_Matching_Utility(bool[,] bpGraph, int u, bool[] seen, int[] matchR){int N = bpGraph.GetLength(1);for (int v = 0; v < N; v++){if (bpGraph[u, v] && !seen[v]){seen[v] = true;if (matchR[v] < 0 || Maximum_Bipartite_Matching_Utility(bpGraph, matchR[v], seen, matchR)){matchR[v] = u;return true;}}}return false;}public static int Maximum_Bipartite_Matching(bool[,] bpGraph){int M = bpGraph.GetLength(0);int N = bpGraph.GetLength(1);int[] matchR = new int[N];for (int i = 0; i < N; i++){matchR[i] = -1;}int result = 0;for (int u = 0; u < M; u++){bool[] seen = new bool[N];for (int i = 0; i < N; i++){seen[i] = false;}if (Maximum_Bipartite_Matching_Utility(bpGraph, u, seen, matchR)){result++;}}return result;}}public static partial class GalleryDrive{public static string MBM(){bool[,] bpGraph = new bool[,] {{ false, true, true, false, false, false },{ true, false, false, true, false, false },{ false, false, true, false, false, false },{ false, false, true, true, false, false },{ false, false, false, false, false, false },{ false, false, false, false, false, true }};return ("Maximum number of applicants that can get job is " + Algorithm_Gallery.Maximum_Bipartite_Matching(bpGraph));}}
}



![[VLDB 2022]Butterfly Counting on Uncertain Bipartite Graphs](https://img-blog.csdnimg.cn/img_convert/1b73ccd0e116142bc0cca4fe865cd11b.png)
![二分匹配大总结——Bipartite Graph Matchings[LnJJF]](https://img-blog.csdnimg.cn/f12f5708538c44c08101ac60cf3d8342.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATG5KSkY=,size_20,color_FFFFFF,t_70,g_se,x_16)











