求二分图最大匹配——Hopcroft-Krap算法

二分图最大匹配-HK算法的简单理解和实现 求一个二分图的最大匹配,朴实的匈牙利算法的复杂度为O (VE),优点是代码量很少,而且顶点数目在1000以内的时候表现不错。 bool dfs(int u,int tot){ for(int i = head[u];i != -1; i = e[i].nxt){ int v= e[i].v; if(vis[v] == tot) continue; vis[v] = tot; if... 阅读详情

本文是对二分图大讲堂这篇文章中Hopcroft-Krap算法代码实现的详细注释。

HK算法的基本原理

Hopcroft-Karp算法先使用BFS查找多条增广路,然后使用DFS遍历增广路(累加匹配数,修改匹配点集),循环执行,直到没有增广路为止。
Hopcroft-Karp算法的BFS遍历只对点进行分层(不标记是匹配点和未匹配点),然后用DFS遍历看上面的层次哪些是增广路径(最后一个点是未匹配的)。
BFS过程可以看做是图像树结构一样逐层向下遍历,还要防止出现相交的增广路径。

二分图大讲堂中给出了HK算法步骤的通俗解释

设U和V是图G的二分图,M是从U到V的匹配
(1)使用BFS遍历对图的点进行分层,从X中找出一个未匹配点v,(所有v)组成第一层,接下的层是这样形成的——都是查找匹配点(增广路性质),直到在V中找到未匹配点才终止查找,对X其他未匹配点同样进行查找增广路径(BFS只分层不标记是否匹配点)
(2)使用DFS遍历查找(1)形成的增广路,找到就匹配数就累加1
(3)重复(1)(2)操作直到找不出增广路径为止

而二分图最大匹配之Hopcroft-Karp算法里给了比较学术化的步骤,有兴趣可以看一下

代码注解如下

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;

bool flag;
int p, n;
// 两个集合: X和Y
// Mx,My记录结点的匹配顶点
int Mx[MAXN], My[MAXN], Nx, Ny;
// dx,dy是结点的BFS遍历层次
int dx[MAXN], dy[MAXN], dis;
bool vst[MAXN], g[110][310];

bool searchP()
{
    queue<int> Q;
    dis = INF;
    memset(dx, 0x3f, sizeof dx);
    memset(dy, 0x3f, sizeof dy);
    // 使用BFS遍历对图的点进行分层,从X中找出一个未匹配点v
    // (所有v)组成第一层,接下来的层都是这样形成——每次查找
    // 匹配点(增广路性质),直到在Y中找到未匹配点才停止查找,
    // 对X其他未匹配点同样进行查找增广路径(BFS只分层不标记
    // 是否匹配点)
    // 找出X中的所有未匹配点组成BFS的第一层
    for (int i = 1; i <= Nx; ++i)
    {
        if (Mx[i] == -1)
        {
            Q.push(i);
            dx[i] = 0;
        }
    }
    while (!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        // 该路径长度大于dis,等待下一次BFS扩充
        // dis是到Y集合的长度,所以dis一定是一个奇数
        if (dx[u] > dis) break;
        for (int v = 1; v <= Ny; ++v)
        {
            // (u,v)之间有边且v还没有分层
            // 分配v的层次
            if (g[u][v] && dy[v] == -1)
            {
                dy[v] = dx[u] + 1;
                // v是未匹配点,停止延伸(查找)
                // 得到本次BFS的最大遍历层次
                if (My[v] == -1) dis = dy[v];
                // v是匹配点,继续延伸
                else
                {
                    dx[My[v]] = dy[v] + 1;
                    Q.push(My[v]);
                }
            }
        }
    }
    // 若dis为INF说明Y中没有未匹配点,也就是没有增广路径了
    return dis != INF;
}

// 用DFS遍历查找BFS形成的增广路,如果可以找到增广路就停止遍历并返回true
bool DFS(int u)
{
    for (int v = 1; v <= Ny; ++v)
    {
        if (!vst[v] && g[u][v] && dy[v] == dx[u] + 1)
        {
            vst[v] = 1;
            // 层次(也就是增广路径的长度)大于本次查找的dis
            // 是searchP中被break的情况,也就是还不确定是否是增广路
            // 只有等再次调用searchP再判断
            if (My[v] != -1 && dy[v] == dis) continue;
            // 是增广路径,更新匹配集
            if (My[v] == -1 || DFS(My[v]))
            {
                My[v] = u;
                Mx[u] = v;
                return true;
            }
        }
    }
    return false;
}

// 查找二分图的最大匹配
int MaxMatch()
{
    int res = 0;
    // 每个结点的匹配顶点置空
    memset(Mx, 0x3f, sizeof Mx);
    memset(My, 0x3f, sizeof My);
    // 如果BFS可以找到增广路径
    while (searchP())
    {
        memset(vst, 0 , sizeof vst);
        for (int i = 1; i <= Nx; ++i)
        {
            // 用DFS查找增广路径,增广路径一定从未匹配点开始
            // 如果查找到一个增广路径,匹配数加一
            if (Mx[i] == -1 && DFS(i))
                ++res;
        }
    }
    return res;
}
C++实现Hopcroft Karp算法:最大匹配问题 然后,我们遍历当前队列中的所有节点u,并对其连接的每个右侧节点v进行如下操作:如果match [v]尚未被标记,则将其标记为匹配,设置d [match [v]] = d [u] + 1,并将match [v]从队列中移除。我们还定义了向量d和match,其中d [i]表示从左侧节点i到根(即未匹配节点)的最短距离,而match [j]表示右侧节点j的匹配节点。Hopcroft-Karp算法是基于BFS的增广路算法,它的时间复杂度为O(E * sqrt(V)),其中E是边的数量,V是点的数量。 阅读详情

相关推荐

C/C++ hopcroft karp霍普克洛夫特-卡普算法详解及源码

Hopcroft-Karp算法的基本思想是通过不断寻找增广路径来不断增加匹配的边数,直到无法再找到增广路径为止。增广路径是指在一个匹配中,从一个未匹配点开始,经过一系列的匹配边和未匹配边,最终到达另一个未匹配点的路径。Hopcroft-Karp算法的优点是,它具有较低的时间复杂度,适用于大规模的图。它的缺点是实现起来较为复杂,需要使用BFS或DFS进行图的遍历,同时需要维护一个距离数组。Hopcroft-Karp算法(霍普克洛夫特-卡普算法)是一种用于解决二部图最大匹配问题的有效算法。

希望我的博客,能帮上你解决学习中工作中所遇到的问题 7210

Hopcroft-Karp 算法

Hopcroft-Karp算法是求二分图最大匹配的匈牙利算法的优化算法。代码虽然比匈牙利算法的代码量大,复杂一些,但时间复杂度优化不少。这里先暂记一下模板,里面有注释。日后在补上说明和讲解,其实我不会证明。学算法都只是学会了怎么用,没学懂过证明。(惭愧)。 以下第一张图是洛谷的模板题使用匈牙利的情况。 第二张是使用 Hopcroft-Karp的情况。 代码不记得是不是模板题的代码,但...

SuperBvs的博客 3339

TwinCAT报SSE invalid operation错误

错误类型 TwinCAT程序中报出以下错误: 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 **** 383 ms | 'Port_851' (851): Exception (Exception Code: 0xc0000090, SSE invalid operation) in PLC Application Untitled1 Instance, Task PlcTask (RBP: 0xffffb3016c80ecc0, RIP: 0xffffe708ee5b5f53, RSP:

akadiao的博客 4162

Hopcroft-Karp算法

Hopcroft-Karp算法该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。原理为了降低时间复杂度,可以在增广匹配集合M时,每次寻找多条增广路径。这样就可以进一步降低时间复杂度,可以证明,算法的时间复杂度可以到达O(n^0.5*m),虽然优化不了多少,但在实际应用时,效果还是很明显的。基本算法该算法主要是对匈牙利算法的优化,...

码农的一亩三分地 1391

华科软院研究生第一学期的事项(奖学金、学业、考试等)

奖助 研究生补助 每月500,全年共6000元 每个月月底学院会打到银行卡里 碰上开学、过年会延后发放 17年10月底发了9、10两个月的钱 18年3月底发了2、3月的钱 学业奖学金 17届全日制每人都有 按照考研最后综合成绩排名 前16 10000 前80 8000 其他 4000 大概11月底发 注意:第一年如果有挂科的话,第二年就不能参加学业奖学金评...

sjdeak的博客 3706

MySQL服务启动失败?手把手教你排查NET HELPMSG 3534错误(附完整修复流程)

本文针对Windows平台上MySQL服务启动失败并提示NET HELPMSG 3534错误的常见问题,提供了系统性的排查与修复指南。文章深入剖析了错误本质,并手把手教你通过查看MySQL错误日志、检查并初始化数据目录、修正Windows服务配置、排查my.ini配置文件陷阱等核心步骤,彻底解决这一棘手问题,帮助开发者和运维人员快速恢复数据库服务。

wdx0123456的博客 895

Hopcroft-karp 算法

Hopcroft-Karp算法 该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。时间复杂度O(n^0.5*m) 思路: 用bfs来找出多条不相交的最短增广路,形成极大增广路集,然后可以用匈牙利多路增广。 bfs要找最短的增广路,是因为增广路的长度每增加1,他的匹配数也增加1,所以最短保证答案的准确。 每一

Fb_by 4559

idea 编译打包nacos2.0.3源码,生成可执行jar 包常见问题

idea 编译打包nacos2.0.3源码,生成可执行jar 包常见问题

fyihdg的专栏 1218

HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)

题目链接:点击查看 题目大意:给出n个人和m个雨伞,t分钟后就要下雨了,现在给出每个人的坐标和速度,以及雨伞所在的坐标,每个雨伞只能容纳一个人,题目问最多有多少个人能不被淋到 题目分析:二分图最大匹配,但是对算法有要求,用匈牙利时间复杂度是O(VE),会超时,用最大流虽然时间复杂度是O(sqrt(V)E),但是有N*M*2条边,会爆内存,所以只能选择用HK算法,时间复杂度也是O(sqrt(V)...

Falcon的博客 397

手把手教你:如何为自制的STM32H7飞控板适配PX4固件(基于NuttX)

本文详细介绍了如何为自制的STM32H7飞控板适配PX4固件,基于NuttX系统进行移植。从硬件设计规范到软件环境配置,再到PX4固件的移植与调试,提供了完整的实战指南。特别分享了如何复用FMU-v6u参考设计以节省开发时间,并解决了常见问题,帮助开发者快速实现高性能飞控系统的搭建。

weixin_27697385的博客 475

我在腾讯上构建了一个人人能用的机载适航知识库

当ChatGPT掀起生成式AI的浪潮时,工程师们发现了一个尴尬的现实:询问“如何编写软件合格审定计划”,AI的回答可能充满似是而非的术语,却无法精确关联FDO-178C的对应内容。现在市面上有许多的AI大模型+适航知识库的方案,之前我的文章介绍了一种本地大模型加知识库的解决方法。此外,ima知识库的容量大小可以到30GB(企鹅大气),只要管理好文件的格式,理论上是完全可以把机载适航相关的内容容纳进去的。后续会不断增加适航法规,适航规章,适航标准,适航书籍,适航相关的论文,以及网上其他一些优秀的内容。

qq_41854911的博客 1223

HDU2389 Rain on your Parade 二分图匹配——Hopcroft_Karp算法

Problem Address:http://acm.hdu.edu.cn/showproblem.php?pid=2389   【前言】   做个二分图的专题。 遇到这道顶点数3000的题目。 用匈牙利邻接表、邻接矩阵,以及匈牙利非递归版本交了三次,均TLE。 然后找到解题报告,说是HK算法。 网上介绍HK算法的资料挺多,但讲解的挺少,拼凑着突然觉悟了。   【思路】

Human_CK的专栏 1025

【从零到一】Jetson Nano上YOLOv5部署完全攻略:零基础小白也能玩转边缘AI推理

文章摘要: 本文详细介绍了在Jetson Nano边缘设备上部署YOLOv5目标检测模型的完整流程。从硬件准备、系统镜像烧录、基础环境配置,到CUDA/cuDNN验证、Python虚拟环境搭建及PyTorch安装,逐步指导开发者完成部署准备。教程兼顾理论原理与实践操作,提供Python和C++两种实现方案,并涵盖TensorRT优化、实时检测等生产级应用场景,帮助零基础开发者快速掌握边缘AI推理技术,实现高性能目标检测应用。

LXY_LOVE36的博客 369

【HDU】2389 Rain on your Parade 二分匹配 Hopcroft-Krap算法

传送门:【HDU】2389 Rain on your Parade

poursoul 1577

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

RK3588, FFmpeg 拉流 RTSP, mpp 硬解码转RGB

J。 2342

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

HDU 2389 Rain on your Parade(二分图匹配的hopcroft-carp算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2389Problem DescriptionYou’re giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It’s a warm, sunn...

baodream的博客 372

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

kuangbin带你飞 匹配问题 二分匹配 + 二分图多重匹配 + 二分图最大权匹配 + 一般图匹配带花树...

二分匹配:二分图的一些性质 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 1。一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一...

weixin_30822451的博客 707

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

二分图大讲堂——彻底搞定最大匹配数(最小覆盖数)、最大独立数、最小路径覆盖、带权最优匹配...

二分图大讲堂——彻底搞定最大匹配数(最小覆盖数)、最大独立数、最小路径覆盖、带权最优匹配 文本内容框架: §1图论点、边集和二分图的相关概念和性质 §2二分图最大匹配求解 匈牙利算法、Hopcroft-Karp算法 §3二分图最小覆盖集和最大独立集的构造 §4二分图最小路径覆盖求解 §5二分图带权最优匹配求解 Kuhn-Munkers算法 §6小结 每章节都...

qiudesuo的专栏 1738

Hopcroft-Karp算法 poj-1469 COURSES

Hopcroft-karp算法 该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。 使用情形 给定一个二分图,求其最大匹配。 原理简述 在增广匹配集时,每次寻找多条增广路径,以进一步减少时间复杂度。 步骤及示例演示 dx【】、dy【】 分别表示二分图左右不顶点的距离标号 mx【】、my【】 分别表示二分图左右部顶点的距离标号 1、我们每次从所有未匹配的左部节点开始BFS,进行距离标号。 2、对于每一个队列中的左部节点X,考虑与它相邻的所有

饮闲的博客 810

二分最大匹配(匈牙利算法+HK算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2063 匈牙利算法:http://blog.youkuaiyun.com/dark_scope/article/details/8880547 Hopcroft-Karp算法:http://blog.youkuaiyun.com/xu3737284/article/details/8973720 问题概述: 一场聚会上有n个男生m

加载中... 1874

二分图最大匹配之Hopcroft-Karp算法

Hopcroft-Karp算法 该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。 原理 为了降低时间复杂度,可以在增广匹配集合M时,每次寻找多条增广路径。这样就可以进一步降低时间复杂度,可以证明,算法的时间复杂度可以到达O(n^0.5*m),虽然优化不了多少,但在实际应用时,效果还是很明显的。 基本算法 该算法主

Wall_F的专栏 1万+

二分图匹配 Hopcroft-Carp (HK) 算法详解 附例题

了解这个算法之前 首先了解一个概念 :增广路 增广路 :简单的说 ,是二分图匹配中的一条边,他总是从 左边集合的一个点出发通过一条没有被匹配的边连接到右边集合,再从该点通过一条 匹配过的边连接到右边集合。 图1为 正常的二分图 图2为二分图的最大匹配 图3 为二分图最大匹配中的增广路 两条 紫色一条 黄色一条。 了解这个算法之前,还需要对一个算法进行比较: 匈牙利算法 匈牙利算法 ...

一只酷酷光儿的博客 3778

二分图最大匹配之Hopcroft-Karp算法 详解

Hopcroft-Karp算法 原链接 该算法由John.E.Hopcroft和Richard M.Karp于1973提出,故称Hopcroft-Karp算法。 原理 为了降低时间复杂度,可以在增广匹配集合M时,每次寻找多条增广路径。这样就可以进一步降低时间复杂度,可以证明,算法的时间复杂度可以到达O(n^0.5*m),虽然优化不了多少,但在实际应用时,效果还是很明显的。 基本算法 该算...

qq_41668093的博客 2198

hdu 2389 Rain on your Parade (二分匹配 Hc 算法)

题目链锁 http://acm.hdu.edu.cn/showproblem.php?pid=2389 先生成最短增广路,在此基础进行增广,复杂度sqrt(n)*e #include #include #include #include #include #include #include #include #include #include #include using namesp

To_c_t_w 429
上一篇: HDU 6333 莫队分块 + 逆元打表求组合数
下一篇: LightOJ1356 最大独立集 HK算法 素数分解
LucianoSi
博客等级 码龄12年 1粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值