二分图匹配 匈牙利
二分图及相关概念
- 二分图:又称二部图,是一种特殊的图结构,其顶点集可以被划分为两个互不相交的子集和,并且图中所有的边都连接着中的顶点和中的顶点,和内部没有边。
- 匹配:在二分图中,匹配是指一组边的集合,其中任意两条边都没有公共顶点。
- 最大匹配:是指在所有可能的匹配中,边数最多的匹配。
实现步骤
- 初始化:将所有顶点标记为未访问,所有边都初始化为未匹配状态。
- 遍历顶点:从二分图的一侧顶点集合中选取一个未匹配的顶点开始遍历。
- 寻找增广路径:从出发,尝试找到一条增广路径。对于的每个邻接顶点,如果未匹配,那么就找到了一条增广路径;如果已经匹配,但是其匹配的顶点可以通过其他路径找到一个新的匹配顶点,那么也找到了一条增广路径,这可以通过递归地调用寻找增广路径的函数来实现。
- 更新匹配:一旦找到增广路径,就沿着该路径更新匹配,即将路径上的匹配边变为未匹配边,未匹配边变为匹配边。
重复步骤 2-4,直到找不到新的增广路径为止,此时得到的匹配就是二分图的最大匹配。
板子
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
vector<int> G[N]; // 邻接表存储二分图
int match[N]; // 记录匹配的顶点
bool vis[N]; // 标记是否访问过
// 寻找增广路径
bool dfs(int u)
{
for (int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if (!vis[v])
{
vis[v] = true;
// 如果v未匹配或者v的匹配点可以找到新的匹配
if (match[v] == -1 || dfs(match[v]))
{
match[v] = u;
return true;
}
}
}
return false;
}
// 匈牙利算法求最大匹配
int search(int n)
{
int ans = 0;
memset(match, -1, sizeof(match)); //初始化
for (int i = 1; i <= n; i++)
{
memset(vis, 0, sizeof(vis));
if (dfs(i))
ans++;
}
return ans;
}
int main()
{
return 0;
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18741859

浙公网安备 33010602011771号