码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • acwing算法基础之搜索与图论--匈牙利算法求二分图的最大匹配数


    目录

    • 1 基础知识
    • 2 模板
    • 3 工程化

    1 基础知识

    二分图中的最大匹配数:从二分图中选择一些边(这些边连接集合A和集合B,集合A中结点数目为n1,集合B中结点数目为n2),设为集合S,其中任意两条边不共用一个结点。求集合S的最大元素数目,即二分图中的最大匹配数。

    匈牙利算法的关键步骤:

    1. 初始化匹配数组match[1~n2] = 0。其中match[b] = a,表示集合B中的结点b匹配了集合A中的结点a。
    2. 遍历集合A中的每一个结点a:初始化状态数组st[1~n2] = false,其中st[b] = false表示集合B中的结点b没有被访问。然后,find(x),如果它返回true,那么答案加1。
    bool find(int a) {//a为集合A中的结点
    	for (auto b : g[x]) {
    		if (!st[b]) {//如果结点b没有被访问
    			st[b] = true;
    			if (match[b] == 0 || find(match[b])) { //如果结点b没有被匹配,或者结点b匹配了的结点可以找到新的
    				match[b] = a;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 最终返回答案,即为该二分图的最大匹配数。

    2 模板

    int n1, n2;     // n1表示第一个集合中的点数,n2表示第二个集合中的点数
    int h[N], e[M], ne[M], idx;     // 邻接表存储所有边,匈牙利算法中只会用到从第一个集合指向第二个集合的边,所以这里只用存一个方向的边
    int match[N];       // 存储第二个集合中的每个点当前匹配的第一个集合中的点是哪个
    bool st[N];     // 表示第二个集合中的每个点是否已经被遍历过
    
    bool find(int x)
    {
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (!st[j])
            {
                st[j] = true;
                if (match[j] == 0 || find(match[j]))
                {
                    match[j] = x;
                    return true;
                }
            }
        }
    
        return false;
    }
    
    // 求最大匹配数,依次枚举第一个集合中的每个点能否匹配第二个集合中的点
    int res = 0;
    for (int i = 1; i <= n1; i ++ )
    {
        memset(st, false, sizeof st);
        if (find(i)) res ++ ;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    3 工程化

    题目1:求二分图的最大匹配。

    #include 
    #include 
    #include 
    
    using namespace std;
    
    const int N = 510;
    int n1, n2, m;
    vector<vector<int>> g(N);
    int match[N];
    bool st[N];
    
    bool find(int a) {
        for (auto b : g[a]) {
            if (!st[b]) {
                st[b] = true;
                if (match[b] == 0 || find(match[b])) {
                    match[b] = a;
                    return true;
                }
            }
        }
        return false;
    }
    
    int main() {
        cin >> n1 >> n2 >> m;
        int a, b;
        while (m--) {
            cin >> a >> b;
            g[a].emplace_back(b);
        }
        
        int res = 0;
        for (int i = 1; i <= n1; ++i) {
            memset(st, 0, sizeof st);
            if (find(i)) res++;
        }
        
        cout << res << endl;
        
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
  • 相关阅读:
    浮躁中寻觅一分宁静
    初出茅庐的小李博客之单片机基础知识
    信创再添佳绩!2022信创“大比武”ZStack 斩获两大奖项!
    Pytorch分布式训练
    CompletableFuture 方法总结
    春秋云镜 CVE-2015-9331
    文举论金:黄金原油全面走势分析策略独家指导
    深入理解嵌入式系统【基于Arduino的嵌入式系统入门与实践】相关基础知识概述:嵌入式系统/技术(定义、分类、组成、简介);Arduino开发板分类;VCC,GND;模拟信号和数字信号;杜邦线,面包板
    Nginx中实现自签名SSL证书生成与配置
    windows下修改mysql的max_allowed_packet的值
  • 原文地址:https://blog.csdn.net/YMWM_/article/details/134360071
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号