二分图匹配 匈牙利

二分图及相关概念

  • 二分图:又称二部图,是一种特殊的图结构,其顶点集可以被划分为两个互不相交的子集和,并且图中所有的边都连接着中的顶点和中的顶点,和内部没有边。
  • 匹配:在二分图中,匹配是指一组边的集合,其中任意两条边都没有公共顶点。
  • 最大匹配:是指在所有可能的匹配中,边数最多的匹配。

实现步骤

  1. 初始化:将所有顶点标记为未访问,所有边都初始化为未匹配状态。
  2. 遍历顶点:从二分图的一侧顶点集合中选取一个未匹配的顶点开始遍历。
  3. 寻找增广路径:从出发,尝试找到一条增广路径。对于的每个邻接顶点,如果未匹配,那么就找到了一条增广路径;如果已经匹配,但是其匹配的顶点可以通过其他路径找到一个新的匹配顶点,那么也找到了一条增广路径,这可以通过递归地调用寻找增广路径的函数来实现。
  4. 更新匹配:一旦找到增广路径,就沿着该路径更新匹配,即将路径上的匹配边变为未匹配边,未匹配边变为匹配边。
    重复步骤 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;
}
posted @ 2025-02-27 20:18  流氓兔LMT  阅读(28)  评论(0)    收藏  举报