当前位置: 首页 > news >正文

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 模板

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 ++ ;
}

3 工程化

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

#include <iostream>
#include <cstring>
#include <vector>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;
}

相关文章:

  • Win Docker Desktop + WSL2 部署PyTorch-CUDA服务至k8s算力集群
  • 个人Typora存储图片专用
  • 破解tomcat密码并上传webshell
  • 双写绕过 [极客大挑战 2019]BabySQL 1
  • 社区牛奶直供站:创新供应链,满足消费者需求
  • 三、Vue3中使用Pinia修改State的方法
  • bzero和memset的区别
  • Spring-Security前后端分离权限认证
  • Android 基本属性绘制文本对象FontMetrics
  • 小程序怎么获取textarea的值?
  • 算法通关村第十六关青铜挑战——原来滑动窗口如此简单!
  • 【C++】一维字符数组 与 二维字符数组
  • Jenkins CICD过程常见异常
  • mysql核心知识整理
  • 11.14 知识总结(视图层、模层板)
  • [ JavaScript ] 数据结构与算法 —— 链表
  • Cumulo 的 ClojureScript 模块已经成型
  • Laravel5.4 Queues队列学习
  • Leetcode 27 Remove Element
  • Map集合、散列表、红黑树介绍
  • MobX
  • MySQL用户中的%到底包不包括localhost?
  • vue:响应原理
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • postgresql行列转换函数
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • 策略 : 一文教你成为人工智能(AI)领域专家
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (04)odoo视图操作
  • (6)STL算法之转换
  • (8)Linux使用C语言读取proc/stat等cpu使用数据
  • (附表设计)不是我吹!超级全面的权限系统设计方案面世了
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)shell调试方法
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET 的静态构造函数是否线程安全?答案是肯定的!
  • .net 后台导出excel ,word
  • .Net 路由处理厉害了
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET实现之(自动更新)
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [Android]使用Android打包Unity工程
  • [AutoSar]BSW_Memory_Stack_003 NVM与APP的显式和隐式同步
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [BT]BUUCTF刷题第8天(3.26)
  • [BUUCTF NewStarCTF 2023 公开赛道] week3 crypto/pwn
  • [BZOJ4010]菜肴制作
  • [CareerCup] 13.1 Print Last K Lines 打印最后K行
  • [CF543A]/[CF544C]Writing Code