二分图最大匹配问题(匈牙利算法)

【学会就脱单算法】匈牙利算法之飞行员配对问题(二分图最大匹配) hello, everyone, I'm Arabic1666!                 首先看题如下,看懂问题才能解决问题飞行员配对(二分图最大匹配) 题目来源: 网络流24题基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员... 阅读详情

什么是二分图

如果一个无向图的的顶点可以分为两个互不相交的子集A和B,那么它就是二分图。也就是说,A、B内部不存在连边,所有连边都一头连着A中的顶点,另一头连着B中的顶点。

什么是二分图最大匹配?

二分图最大匹配问题,就是在A、B这两个集合中,不断选择两个存在连线的点,把他们连起来,求最多可以有多少条连线的问题。

怎么解?

匈牙利算法的核心在于:从A集合中选择一个点,然后将与其相连的B中的点依次对照,如果B中的点尚未匹配,那就将这两个点进行匹配,然后遍历A中的下一个点。接着继续访问与其相连的B中的点,如果B中的点已经被匹配了,那就尝试递归地将与B中的这个点相匹配的A中的点换一个匹配对象(递归地执行上述过程)。这其实就是在寻找增广路。当找到一条增广路,就能使得匹配数+1。如此一来,当我们把A中的所有点遍历之后,就能得到最大的匹配了。

上面这个过程说起来有点绕口,我也想了很久才想明白。

在敲代码的时候还要注意一点,我们一直都是对于A中的点进行DFS,而被访问到的B中的点,需要在被访问到的时候,设置vis为true, 否则会造成死循环。

上面说的“对A中的点进行DFS”怎么理解呢?由于增广路是:未匹配边-匹配边-未匹配边-匹配边-未匹配边,即开头结尾都要是未匹配边,因此我们设定A集合出发的边都是未匹配边,B集合出发的都是匹配边。然后,由于匹配边是确定的,因此在寻找增广路时,不需要对B中的点进行DFS,只需将与B点匹配的A中的点进行DFS即可,这样才能满足增广路的要求。

题目

这是一道模板题:https://uoj.ac/problem/78

从前一个和谐的班级,有 nl 个是男生,有 nr 个是女生。编号分别为 1,…,nl 和 1,…,nr。

有若干个这样的条件:第 v 个男生和第 u 个女生愿意结为配偶。

请问这个班级里最多产生多少对配偶?

输入格式
第一行三个正整数,nl,nr,m。

接下来 m 行,每行两个整数 v,u 表示第 v 个男生和第 u 个女生愿意结为配偶。保证 1≤v≤nl,1≤u≤nr,保证同一个条件不会出现两次。

输出格式
第一行一个整数,表示最多产生多少对配偶。

接下来一行 nl 个整数,描述一组最优方案。第 v 个整数表示 v 号男生的配偶的编号。如果 v 号男生没配偶请输出 0。

样例一
input
2 2 3
1 1
1 2
2 1

output
2
2 1

explanation
1 号男生跟 2 号女生幸福地生活在了一起~

2 号男生跟 1 号女生幸福地生活在了一起~

样例二
input
2 2 2
1 1
2 1

output
1
1 0

explanation
班上一个女神一个女汉子,两个男生都去追女神。一种最优方案是:

1 号男生跟 1 号女生幸福地生活在了一起~

2 号男生孤独终生。= =||

限制与约定
1≤nl,nr≤500,1≤m≤250000。

时间限制:1s
空间限制:256MB

这很明显是一个二分图最大匹配问题,由于男生女生的编号都是从1开始,因此为了能便于区分,我们将女生的编号x暂时设置为x+nl, 这样就能保证每个人编号的唯一性。

代码如下:

//二分图最大匹配
#include <bits/stdc++.h>
using namespace std;

#define MAXN 505
#define INF (1 << 31)

bool vis[MAXN * MAXN];
int nl, nr, m;
int girl[MAXN];
int match[MAXN * 3];

struct edge
{
    int from, to, next = 0;
} e[MAXN * MAXN];

int head[3 * MAXN];
int js_edges = 0;

void add(int u, int v)
{
    e[++js_edges].from = u;
    e[js_edges].to = v;
    e[js_edges].next = head[u];
    head[u] = js_edges;
}

bool dfs(int x)
{
    vis[x] = true;
    //cout << "x " << x << endl;
    int nd = head[x];
    while (nd != 0)
    {
        if (!vis[e[nd].to])
        {
            vis[e[nd].to]=true;//防止来回横跳,无法退出
            //cout << "     " << e[nd].to << endl;
            if (!match[e[nd].to] || dfs(match[e[nd].to]))
            {
                match[x] = e[nd].to;
                match[e[nd].to] = x;
                
                return true; //找到增广路或者能够创建连线
            }
        }
        nd = e[nd].next;
    }

    return false;
}

int main()
{
    scanf("%d%d%d", &nl, &nr, &m);

    int v, u;
    for (int i = 0; i < m; ++i)
    {
        scanf("%d%d", &v, &u);
        //人的id划分:男生都加nr, 女生不变
        add(v, u + nl);
    }

    int ans = 0;
    for (int i = 1; i <= nl; ++i)
    {
        memset(vis, 0, sizeof(vis));
        if (dfs(i))
            ++ans;
    }

    printf("%d\n", ans);
    for (int i = 1; i <= nl; ++i)
    {
        if (match[i] == 0)
            printf("0 ");
        else
            printf("%d ", match[i] - nl);
    }
    printf("\n");
}

转载请注明原文:https://www.longjin666.top/?p=1122

匈牙利算法解析:二分图最大匹配问题实战 二分图匹配是图论中的经典问题,用于解决两类对象之间的最优配对需求。匈牙利算法通过寻找增广路径的策略,能在O(VE)时间复杂度内解决最大匹配问题。该算法在稀疏图上表现优异,适用于任务分配、资源调度等实际场景。以杭电OJ 2063过山车问题为例,展示了如何将乘客座位偏好建模为二分图,并通过邻接表存储和递归实现高效求解。算法实现中需注意顶点编号处理、重复边过滤等细节,其核心思想也可扩展应用于带权匹配等变种问题。 阅读详情

相关推荐

告别Overleaf!本地LaTeX环境配置:VSCode+TeXLive完全指南(Windows/Mac双平台)

本文详细介绍了如何在Windows和Mac平台上配置本地LaTeX环境,使用VSCode和TeXLive打造高效的专业写作工作流。从TeXLive安装到VSCode插件配置,再到高级技巧与性能优化,帮助用户摆脱Overleaf限制,实现更快速、更私密的学术写作体验。

3c4x5z6v7b的博客 952

二分图最大匹配

先上定义: 一、二分图 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图 也就是一个图被划分成了两个不相交的集合,集合内部没有边相连。 二、匹配 1、匹配 在一个二分图G中,它的一个子集...

curry___的博客 2978

从零到一:Qt与PCL的跨平台开发环境搭建全攻略

本文详细介绍了从零开始搭建Qt与PCL跨平台开发环境的完整流程,涵盖Windows、Linux和macOS三大平台。重点解析了Qt5与Qt6版本选择、PCL库安装配置、VTK集成等关键技术要点,并提供跨平台CMake项目模板和常见问题解决方案,助力开发者快速构建三维点云处理应用。

weixin_29280657的博客 384

二分图的最大匹配

一、概念: 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交集U和V,使得每一条边都分别连接U、V中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有「含奇数条边的环」的图。图 1 是一个二分图。为了清晰,我们以后都把它画成图 2 的形式。 匹配:在图论中,一个「匹...

dengguan2720的博客 1381

VLP16:使用pointcloud_to_laserscan将三维点云转化为二维LaserScan

velodyne16线激光雷达 VLP16:使用pointcloud_to_laserscan将三维点云转化为二维LaserScan

NEUer_ljx的博客 4620

概率论 知识图谱 + 实战案例解析

本文通过构建概率论知识图谱,系统梳理了从随机试验、概率、条件概率到随机变量与分布的核心概念及其内在联系。结合朴素贝叶斯分类器和蒙特卡洛模拟等实战案例,深入解析了条件概率、独立性及大数定律等理论如何应用于机器学习与实际问题求解,旨在帮助读者建立结构化思维,将理论有效转化为解决实际问题的能力。

weixin_29051193的博客 267

二分图最大匹配——匈牙利算法

二分图最大匹配(一)、二分图的介绍1、定义2、充要条件(二)、二分图的匹配1、二分图的最大匹配2、增广路径3、匈牙利算法(1)、复杂度 (一)、二分图的介绍 1、定义 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点 i 和 j 分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 2、充要条件 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的

hahahahahaha5的博客 1万+

Fluent新手避坑:遇到‘Floating point exception’别慌,这7个排查步骤帮你搞定

本文为Fluent新手提供了7个排查'Floating point exception'错误的实用步骤,包括边界条件检查、时间步长优化、求解器配置等关键技巧。通过系统化的诊断流程,帮助用户快速定位并解决CFD仿真中的浮点异常问题,提升计算稳定性。

weixin_42531886的博客 287

二分图最大匹配问题

二分图最大匹配问题 最近在做的打车项目中,涉及到了用户叫单后,将所有出单司机和所有订单匹配的问题,借此来学习一下二分图的匹配算法。 一、无权二分图最大匹配 首先要区分一下各个概念: 匹配:图G的一个匹配是由一组没有公共端点的不是环的边构成的集合。 匹配有两个重点:1. 匹配是边的集合;2. 在该集合中,任意两条边不能有共同的顶点。 注意:二分图无奇圈。 完美匹配:考虑部集为X={x1 ,x2, …}和Y={y1, y2, …}的二分图,一个完美匹配就是定义从X-Y的一个双射,依次为x1, x2, …

Dream_Glow的博客 3663

第 2 章:PassThrough 直通滤波

通过设置某个维度(如 x、y、z 或 rgb)的取值范围,仅保留该范围内的点,从而达到**点云裁剪(裁边)**或过滤异常值的目的。所有在该范围之外的点会被移除(可选是否保留);点云中包含背景、地面或传感器噪声,需要过滤;通过 z 轴过滤,只保留桌面上方的物体;多轴组合过滤(如同时过滤 x、y、z);可用于地面剔除、车载点云预处理等场景。不支持一次过滤多个字段,可多次调用;仅处理某一层或某一区域的点云数据。原始点云中包含地面、墙面、背景等;在区域裁剪、前景提取中广泛使用;设定一个轴(如z轴);

yumeiguo的博客 337

学Simulink--基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模示例

本文详细介绍了基于Simulink的无迹卡尔曼滤波(UKF)目标跟踪仿真建模方法。首先分析了UKF相比EKF在强非线性场景下的优势,包括无线性化误差、计算效率高和鲁棒性强等特点。接着阐述了UKF的核心原理,重点讲解了无迹变换(UT)的三个关键步骤:Sigma点生成、非线性传播和加权统计重构。文章还详细说明了二维机动目标的状态向量定义、非线性状态转移模型和雷达观测模型。 在Simulink实现部分,提供了完整的建模步骤和核心代码,包括目标运动模型、雷达传感器模型和UKF算法模块的实现。通过蛇形机动场景的仿真实

xiaoheshang_123的博客 89

匈牙利算法求解二分图最大匹配问题

这是一个非常简单的问题,描述如下,给你两部分的点,问你最大匹配数是多少、 简单描述一下算法流程,首先我们先匹配左边,蓝1先匹配红2;接下来到蓝2,只能匹配红2,但是这这时候发现红2已经有主了,根据匈牙利算法思想,这时候回溯,找谁匹配的红2,发现是蓝1,那么这时候看看蓝1还有没有别的选择,一看可以是红4,所以这时候让蓝1匹配红4,蓝2匹配红2;之后是蓝3,先让他匹配红1,没矛盾;现在得到的二分图如下所示 那么现在轮到蓝4了,他只能跟红4匹配,但是红4已经有主了,这时候回溯看蓝1,他还有一个选择是红2,但

ComingLiu的博客 1329

19、多项式基算术:原理与运算详解

本文深入探讨了有限域 $GF(2^m)$ 中的多项式基算术,详细介绍了加法、减法、乘法和平方运算的原理与实现方法。重点分析了多项式基表示形式、模约简技术以及乘法优化策略,如高基数乘法、并行与顺序乘法器设计,并提到了Karatsuba-Ofman算法在减少乘法次数方面的优势。此外,文章还讨论了多项式基算术在密码学、编码理论等领域的应用前景,并展望了未来在高效算法设计与硬件加速方面的研究方向。

yellow的专栏 150

二分图最大匹配问题与匈牙利算法的核心思想

最近在学习图论相关知识,读到二分图最大匹配问题的匈牙利算法,感觉很有意思,所以记录下来。 概念 在假设读者已经了解图论最最基本的概念的基础上(例如:顶点、边、路径、圈),我们先来看一下二分图特有的概念定义。 二分图(Bigraph, Bipartite graph)是一种特殊的图,它的顶点可以被分成两个不相交的集合(UU 和 VV),并且同属一个集合内的点两两不相连(EU=EV=∅E

chutzpah 2707

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

匈牙利算法解决二分图最大匹配问题

匈牙利算法解决二分图最大匹配问题

weixin_72758935的博客 319

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

二部图最大权匹配_学习记录 二分图匹配问题与匈牙利算法及KM算法

一、前言在论文“Real-time Event Detection on Social Data Streams”中,作者首先在每一个时间窗口(分钟级)内利用社区发现算法(Louvain method)得到一个聚类,然后采用带权二分图最大匹配(maximum weighted bipartite matching)对和上一时间窗口的聚类进行聚类链接(Cluster Linki...

weixin_29903713的博客 1619

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

二分图的最大匹配问题(匈牙利算法)

最近在研究二分图问题,有很多东东还是不熟悉!边学习边完善! 【二分图】图中的顶点可以分为两个不相交的点集u和v,因此,二分图中的每个边都是u中的一个点连接v中的一个点。因为u与v不相交,所以图中不存在环。 【二分图的匹配】给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配。 【二分图的最大匹配】包含边数最多的匹配就是最大匹配。(比如,一个

IOT_Change的专栏 1621

【算法】匈牙利算法 - 二分图的最大匹配问题

【算法】匈牙利算法 - 二分图的最大匹配问题 [by_041] 算法过程 遍历所有边: 如果两端都没有入队 边和两端入队 如果左端入队 continue 如果右端入队 找到连接该右端的边的左端 如果被找到的左端可以通过其他边连接其他点 断开已连接的点,连接此处的其他边和遍历中的这条边,维护点入队 该边到此处都没入队,那就前往下一条边 之后再补更证明过程、 ...

Teloy_041的博客 176

匈牙利算法—解决二分图最大匹配问题

先来一份网上比较简单易懂的讲解: 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。 -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世

ZQUSwansea的博客 806

codevs 1922 骑士共存问题||二分图||最大独立集||二分图匹配||Dinic与匈牙利算法的讨论||网络流

**1922 骑士共存问题** **题目描述 Description** 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘 上某些方格设置了障碍,骑士不得进入。对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击。**输入描述 Input Description** 第一行有2 个正整数n 和m (1<=n<

远方 2557

二分图最大匹配问题之匈牙利算法

一:匈牙利算法的原理: 从当前的匹配M(如果木有匹配,则取初始化匹配M为空集)出发,检查每一个未盖点,然后从它出发寻找可增广路,找到可增广路,则沿着这条可增广路进行扩充,直到不存在可增广路为止。 二:根据从未盖点出发寻找可增广路搜索的方法,可以分成:1.DFS增广 2.BFS增广 3.多增广(Hopcroft-Karp算法)   采用DFS思想搜索可增广路并求出最大匹配的代码如下: #d

No_Retreats的专栏 1751

恋爱大法--匈牙利算法--二分图的最大匹配问题

匈牙利算法

m0_62404686的博客 983

素数伴侣(二分图最大匹配问题&匈牙利算法)

题目描述 题目描述 若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最...

wangdongli_1993的博客 1506

二分图的基本概念+二分图的最大匹配问题(匈牙利算法)

今天学了二分图的最大匹配,其中的匈牙利算法。。哦不,其实远不止这个,还有后面的一系列KM、开花树啊什么的算法。反正又是一个异常懵逼的一天。。。 我觉得应该是上课前没有稍微预习一下这个算法是什么,了解个大概,导致上课总是老师讲到后面了,我却还在纠结前面的内容。。可以当作经验教训。        明天他们要去杭电打团体赛。。也不知道怎么的,当时明明跟老师说了,却没报上名。。。这样也好,最近太累了需

x_y_q_的博客 1万+
上一篇: 【题解】Gym – 102307C Common Subsequence
下一篇: POJ1182(食物链):种类并查集
灯珑
博客等级 码龄11年 2755粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值