算法学习笔记(匈牙利算法)

匈牙利算法可以求解二分图的最大匹配问题(二分图:如果无向图 G = ( V , E ) G = (V, E) G=(V,E)的所有点可以分为两个集合 V 1 、 V 2 V_1、V_2 V1V2,所有的边都在 V 1 V_1 V1 V 2 V_2 V2之间,而 V 1 V_1 V1 V 2 V_2 V2的内部没有边,称 G G G是一个二分图。)。

直接引用例题进行解释。

例题:情人节

题目描述

温馨提示:2月14日是第一台通用计算机在宾夕法尼亚大学诞生的日子,在这个特殊的日子,请多花点时间陪陪你的电脑。

现在有 n n n个男孩( 1 ∼ n 1∼n 1n编号), m m m个女孩( 1 ∼ m 1∼m 1m编号),如果一对男女之间存在暧昧关系,那么他俩就有可能成为情侣,现在给出 k k k对暧昧关系,请问最多可以产生多少对情侣?

输入描述

第一行三个整数 n , m , k n,m,k n,m,k ( 1 ≤ n , m ≤ 3 × 1 0 3 , 1 ≤ k ≤ 1 0 4 ) (1 \leq n,m \leq 3 \times 10^3,1 \leq k \leq 10^4) (1n,m3×103,1k104)

接下来 k k k行,每行表示一个暧昧关系 x , y x,y x,y,表示男孩 x x x和女孩 y y y存在暧昧关系。 ( 1 ≤ x ≤ n , 1 ≤ y ≤ m ) (1 \leq x \leq n,1 \leq y \leq m) (1xn,1ym)

输出描述

一行输出结果。

输入样例

3 4 5
1 1
1 2
1 3
2 1
3 4

输出样例

3

解释

至多可以产生三对情侣,分别是 [ 1 , 3 ] , [ 2 , 1 ] , [ 3 , 4 ] [1,3],[2,1],[3,4] [1,3],[2,1],[3,4]

匈牙利算法的流程是这样的:

对访问到的男孩,如果他的暧昧对象没有被分配情侣,那么直接将他们两配对。如果当前访问到的暧昧对象被分配了对象,那么他会试图拆开他们,而被访问的暧昧对象的情侣则会找他其他的暧昧对象试图进行配对,往复下去,如果能结对,那么皆大欢喜。如果不行,则返回到第一层那里,去看他的下一个暧昧对象是否已经和他人配对。

原理是一个贪心的思想:当一个节点匹配后,不改变他已经匹配的状态,只可能更换他的匹配对象,从而实现全局的最大匹配。

采用 d f s dfs dfs来实现。

#include<bits/stdc++.h>
using namespace std;
const int N = 3e3 + 9;vector<int> g[N];
//记录时间戳,防止一次访问时走重复路径,
//代替vis的功能,如果使用vis数组则需要多次清空vis数组
int dfn;        
int p[N];
int vis[N];bool dfs(int x)
{for(auto &y : g[x]){//当前男孩已经被访问过了if(vis[y] == dfn) continue;     vis[y] = dfn;//如果女孩未经匹配或者下一个男孩可以更改匹配对象if(!p[y] || dfs(p[y]))      {p[y] = x;       //进行匹配return true;}}return false;
}void solve()
{int n, m, k; cin >> n >> m >> k;for(int i = 1; i <= k; ++i)     //存图{int x, y; cin >> x >> y;g[x].push_back(y);}int ans = 0;        //存答案for(int i = 1; i <= n; ++i){dfn++;if(dfs(i)) ans++;}cout << ans << '\n';
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _ = 1;while(_--) solve();return 0;
}

PS: K o ¨ n i g König Ko¨nig定理:最小点覆盖数等于最大匹配数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/11503.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解Python的类,实例和type函数

问题起源&#xff1a; class t():pass s1 t() s2 type("Student2",(),{}) isinstance(s1, type), isinstance(s2, type)为什么第一个是false&#xff0c;第二个是true呢 根因定位&#xff1a; 在Python中&#xff0c;一切皆对象&#xff0c;类是对象&#xff0c…

nacos在没有指定数据源的情况下默认使用什么数据库?

在没有特别指定数据源的情况下&#xff0c;Nacos 默认使用内嵌的数据库 Derby 来存储其数据。Derby 是一个轻量级的、基于 Java 的数据库管理系统&#xff0c;适合于开发和测试环境&#xff0c;因为它简单易部署且无需额外的数据库服务器。然而&#xff0c;对于生产环境&#x…

使用ORM快速获取业务对象列表

通常在实际开发中&#xff0c;业务对象的信息是需要来自多个数据表的。 我们如果想要获取这个业务对象&#xff0c;就要先查询数据表&#xff0c;再把查询到的数据依次循环&#xff0c;组合转换封装成业务要使用的对象类型列表。 如果使用了ORM&#xff0c;那么这个过程就可以简…

Stability AI 推出 Stable Artisan,终于可以在Discord上使用Stable Diffusion了!

Stable Diffusion 社区最常见的要求之一是能够直接在 Discord 上使用他们的模型。近期&#xff0c;Stability AI 推出 Stable Artisan&#xff0c;这个需求终于被实现了。 Stable Artisan 支持在 Discord 上生成媒体&#xff0c;由 Stability AI 的尖端图像和视频模型 Stable D…

基于Springboot的实习生管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的实习生管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&a…

mysql group by使用方法实例讲解

MySQL中GROUP BY语句用于对某个或某些字段查询分组&#xff0c;并返回重复记录的第一条&#xff0c;本文章通过实例向大家介绍mysql group by使用方法和需要注意的地方&#xff0c;感兴趣的朋友可以参考一下。 现在有这样一个数据表book idfirst_namelast_namecityage1JasonM…

知乎知+广告推广该如何做?怎么收费?

知乎作为一个汇聚高质量用户群体的知识分享平台&#xff0c;成为了众多品牌和产品推广的优选之地。特别是知乎的“知”广告推广服务&#xff0c;以其精准定向、内容原生的特点&#xff0c;深受广告主青睐。 一、知乎知广告推广基础 1. 什么是知乎知&#xff1f; 知是知乎官方…

C++初阶学习第七弹——探索STL奥秘(二)——string的模拟实现

标准库中的string&#xff1a;C初阶学习第六弹——string&#xff08;1&#xff09;——标准库中的string类-CSDN博客 前言&#xff1a; 在前面我们已经学习了如何使用标准库中的string类&#xff0c;但作为一个合格的程序员&#xff0c;我们不仅要会用&#xff0c;还要知道如…

C++类和对象下——实现日期类

前言 在学习了类和对象的六大成员函数后&#xff0c;为了巩固我们学习的知识可以手写一个日期类来帮助我们理解类和对象&#xff0c;加深对于其的了解。 默认函数 构造函数 既然是写类和对象&#xff0c;我们首先就要定义一个类&#xff0c;然后根据实际需要来加入类的数据与函…

AI编程工具为什么选github copilot?

Github Copilot 是一个奇迹 它的竞争对手&#xff08;Amazon, Google, Meta, 腾讯&#xff09;都是免费的&#xff0c;但每月10-20美元的Github Copilot市场占有率最高。 1、2021年6月上线&#xff0c;比ChatGPT早近一年半 2、GitHub统计&#xff1a; 88%的用户获得效率提升平…

element ui的确认提示框文字样式修改

修改确认提示框文字样式修改&#xff0c;使用message属性修改&#xff1a; 例&#xff1a; js代码&#xff1a; this.$msgbox({title: 确定要删除吗?,message: this.$createElement(p, null, [this.$createElement(span, { style: color: red }, 该素材一旦删除&#xff0c;…

Spring Boot日志

目录 一、日志概述 1、为什么要学习日志&#xff1f; 2、日志的用途 &#xff08;1&#xff09;系统监控 &#xff08;2&#xff09;数据采集 &#xff08;3&#xff09;日志审计 二、日志使用 1、打印日志 &#xff08;1&#xff09;在程序中得到日志对象 &#xf…

QNX SLM介绍

QNX SLM SLM是Qnx中用来加载Application的组件&#xff0c;它可以监控Application行为&#xff08;比如异常退出时重新Application拉起&#xff09;、控制Application间的启动时序。 QNX的SLM与Android RC文件类似。 下面摘自QNX官网介绍 System launch and monitor: launch c…

Redis日常维护流程及技巧:确保稳定性与性能

目录 一、监控和报警设置 1.实时监控&#xff1a;洞察Redis的脉搏 &#xff08;1&#xff09;. 资源使用监控 &#xff08;2&#xff09;. 数据访问模式监控 &#xff08;3&#xff09;. 持久化监控 &#xff08;4&#xff09;. 客户端连接 2.报警机制&#xff1a;快速响…

标准Modbus TCP双网口开关量模块

M140E以太网远程I/O无线数据采集模块是一款工业级、隔离设计、高可靠性、高稳定性和高精度数据采集模块&#xff0c;嵌入式32位高性能微处理器MCU&#xff0c;集成2路工业10/100M自适应以太网模块里面。提供多种I/O&#xff0c;支持标准Modbus TCP&#xff0c;可集成到SCADA、O…

Spring STOMP-连接到消息代理

STOMP 代理中继维护一个与消息代理的“系统”TCP 连接。这个连接仅用于来自服务器端应用程序的消息&#xff0c;不用于接收消息。您可以为此连接配置STOMP凭据&#xff08;即STOMP帧的login和passcode头部&#xff09;。这在XML命名空间和Java配置中都以systemLogin和systemPas…

CentOs搭建Kubernetes集群

kubeadm minikube 还是太“迷你”了&#xff0c;方便的同时也隐藏了很多细节&#xff0c;离真正生产环境里的计算集群有一些差距&#xff0c;毕竟许多需求、任务只有在多节点的大集群里才能够遇到&#xff0c;相比起来&#xff0c;minikube 真的只能算是一个“玩具”。 Kuber…

spring基础使用(案例)

基于xml使用&#xff1a; 准备&#xff1a; 1.Dao层&#xff08;接口&#xff09;&#xff1a; public interface UserDao {public void save(); } 1.1 Dao层&#xff08;实现类&#xff09;&#xff1a; public class UserDaoIim implements UserDao {Overridepublic vo…

Day53代码随想录动态规划part13:300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

Day52 动态规划part13 300.最长递增子序列 leetcode链接&#xff1a;300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 题意&#xff1a;给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列&#xff0c;删除&a…