二部图和匈牙利算法

二部图最大匹配--匈牙利算法 二分图的最大匹配、完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm);不讲带权二分图的最佳匹配。 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是 阅读详情

二部图

二部图的定义:设 G G G是一个图,若 V ( G ) V(G) V(G)有一个划分: V ( G ) = V 1 ⋃ V 2 V(G)=V_1 \bigcup V_2 V(G)=V1​⋃V2​,使得< V 1 V_1 V1​>< V 2 V_2 V2​>都是空图,那么称图 G G G是一个双图,或二部图,或二分图。
简单来说,就是在图中切上一刀,就能使所有点变成孤立的,如下图沿着红线切一刀。在这里插入图片描述
判定二分图一般使用标号法,即将一个顶点和与之相邻的顶点标为不同,若此过程可以一直进行下去,则为二分图。
标号法
代码判定
下面给出深搜的判定,广搜当然也可以(只要维护一个队列)。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
const int N = 505;
int m,n;
int color[N];
int edge[N][N];
 
bool dfs(int v, int c){
    color[v] = c;    //将当前顶点涂色
    for(int i = 0; i < n; i++){    //遍历所有相邻顶点,即连着的点
        if(edge[v][i] == 1){    //如果顶点存在
            if(color[i] == c)    //如果颜色重复,就返回false
                return false;
            if(color[i] == 0 && !dfs(i,-c))    //如果还未涂色,就染上相反的颜色-c,并dfs这个顶点,进入下一层
                return false;   //返回false
        }
    }
    return true;   //如果所有顶点涂完色,并且没有出现同色的相邻顶点,就返回true
}
 
void solve(){
    for(int i = 0; i < n; i++){//对每一点都要判定,因为图可能不是连通的
        if(color[i] == 0){
            if(!dfs(i, 1)){
                printf("NOT BICOLORABLE.\n");
                return;
            }
        }
    }
    printf("BICOLORABLE.\n");
}
 
int main(){
    int u,v;
    while(cin >> n >> m){
        memset(color, 0, sizeof(color));
        memset(edge, 0, sizeof(edge));
        for(int i = 0; i < m; i++){
            cin >> u >> v;    //因为是无向图,所以要往两个方向添加边
            edge[u][v] = 1;    //正着添加
            edge[v][u] = 1;    //反着添加
        }
        solve();
    }
    return 0;
}

匈牙利算法

基本概念:

  • 图 G G G的一个匹配是由一组没有公共端点的不是圈的边构成的集合。
    如图就是之前的图的一个匹配。可知:1. 匹配是边的集合;2. 在该集合中,任意两条边不能有共同的顶点。
    在这里插入图片描述
    就好像参加相亲节目,在不考虑同性恋的情况下,要给匹配合适的对象,有边代表男女嘉宾互有好感。所谓最大匹配,就是节目效果要达到最好,需要尽可能多的互有好感的人配对。
    匈牙利算法可以解决二部图上最大匹配问题。该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。
    ——上面的描述看起来很绕而且有很多概念对不对,下面我们直观地感受一下算法的过程。你会发现,其实我们做的是月老的活。
    首先,我们这个相亲节目在先来后到的基础上很照顾后来的人,会优先考虑后来人的需求,但同时也不能拆散先来的人让他遗憾离场。
    在这里插入图片描述
    现在有三个男嘉宾和三个女嘉宾,男嘉宾有选择权。先从一号男嘉宾开始,他选择了1号女嘉宾,3号女嘉宾成为了他的备胎。
    在这里插入图片描述
    2号男嘉宾来了,他说我也要1号女嘉宾,1号男嘉宾你往后稍稍。节目组这时候劝说1号男嘉宾,哎,你还有3号备胎,你把1号女嘉宾让给2号男嘉宾吧!
    1号一想也是,不如顺便送个人情,于是他换成了3号女嘉宾,2号男嘉宾如愿匹配了1号女嘉宾,并把2号女嘉宾作为了自己的备胎。
    在这里插入图片描述
    这时3号男嘉宾上场,他说我为1号而来!我只要1号!节目组的老好人们又去劝说正和1号牵线的2号男嘉宾。当然2号男嘉宾也同意了,毕竟他还有2号备胎嘛!
    于是本期节目皆大欢喜,大家都牵手成功~
    在这里插入图片描述
    ——这个匹配即是最大匹配,也是完美匹配。
    但是有没有失败而归的情况呢?也是有的:
    假如是这样一张图:
    在这里插入图片描述
    1号2号男嘉宾已经进行了协调和选择:
    在这里插入图片描述
    这时候3号男嘉宾来了,还是非1号不可。节目组劝说2号,2号说我要看看备胎在不在,于是询问3号女嘉宾。
    3号女嘉宾说我得问问1号男嘉宾还有没有备胎。(这是一个递归的过程)
    1号男嘉宾:你就是我的备胎!我的原配已经给2号了!
    于是3号女嘉宾告诉2号,对不起啊,1号没有选择了,我也不当你的备胎了。
    于是2号男嘉宾告诉节目组,对不起啊,我也没有选择了,我不让。
    节目组当然尊重他们的选择,毕竟不能强行拆散,只为了3号男嘉宾。所以节目组告诉3号男嘉宾,对不起啊,你没有牵手成功。
    匹配结果如下:
    在这里插入图片描述
    这是一个最大匹配(满足多数人的需求),但不是完美匹配。

实现代码

题例:POJ1274
大意:有n个槽和m头牛,牛只在特定的几个槽才产奶,求最多几头牛可以产奶。

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
const int maxn = 220;
int n,m;
int mark[maxn];
int match[maxn];
int maze[maxn][maxn];
int ans;

bool Find(int x){
    for(int i = 1;i <= m;++i){
        if(maze[x][i] && !mark[i]){  //如果牛在这里产奶且槽还没问过
            mark[i] = 1;
            if(match[i] == 0 || Find(match[i])){//如果没分配或者分配了但是可以找到别的给那个对象
                match[i] = x;
                return true;
            }
        }
    }
    return false;
}

void slove(){
    memset(match,0,sizeof(match));
    ans = 0;
    for(int i = 1; i <= n;++i){
        memset(mark,0,sizeof(mark));
        if(Find(i))ans++;
    }
}

int main()
{
    while(~scanf("%d%d",&n,&m)){
        for(int i = 1; i <= n;++i)
            for(int j = 1; j <= m;++j)
            maze[i][j] = 0;

        for(int i = 1; i <= n;++i){
            int x;
            scanf("%d",&x);
            for(int j = 1; j <= x;++j){
                    int tmp;
                scanf("%d",&tmp);
                maze[i][tmp] = 1;
            }
        }
        slove();
        printf("%d\n",ans);
    }
    return 0;
}

最大匹配数=最小点覆盖数。因此最小点覆盖也可以转化为最大匹配问题。
一些例题:
POJ1325
POJ3692(需要建补图,是最大独立集的问题)
POJ1469
POJ3041*这个问题的转化比较巧妙了,题目大意是一个网格里有一些障碍物,一发炮弹可以清除同一行或者同一列的障碍物,问最少开几枪。转化障碍物坐标,行坐标为一个集合,列坐标为一个集合,障碍物的坐标连线,使用匈牙利算法。
(大概是考虑在同一行则行坐标相等,尽可能多的为不同的行坐标都能匹配到列坐标。。。)
应用可以参考这篇博客:匈牙利算法—介绍与基本用途

〖进阶篇1〗YAML参数解析:从nav2_params.yaml看机器人导航调优 本文深入解析了ROS2 Nav2导航系统中关键的nav2_params.yaml文件,提供了从定位、行为树、运动控制到环境感知等核心模块的参数调优实战指南。文章通过具体场景案例,如狭窄走廊、动态仓库和高精度对接,详细阐述了如何调整AMCL粒子数、控制器权重、代价地图膨胀半径等参数,以解决机器人导航中的犹豫、碰撞和精度问题,帮助开发者实现从“能用”到“好用”的进阶。 阅读详情

相关推荐

Linux yum源配置以及yum命令讲解

前面为大家介绍了RPM二进制包安装软件,RPM包安装的最大的缺点也提到过,就是依赖性太强,一旦遇到依赖问题,则需要我们手动解决包之间具有依赖性的问题,今天为大家介绍一种可自动解决包之间依赖关系的安装方式:yum。 yum 全称“Yellow dog Updater, Modified”,是一个专门为了解决包的依赖关系而存在的软件包管理器。就好像 Windows 系统上我们通常可以通过各种软件管家实现软件的一键安装、升级和卸载,yum就是Linux 系统中的一键安装工具。yum 解决依赖关系的基本逻辑是:yu

九派Linux的博客 2283

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

二分图最大匹配(一)、二分图的介绍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万+

OpenWebUI外部模型配置异常排查与修复指南

本文详细解析了OpenWebUI外部模型配置异常的常见问题及解决方案,包括隐藏字符、数据库锁死等典型现象。通过错误日志分析和数据库修复实战指南,帮助开发者快速定位并解决配置问题,确保OpenWebUI与第三方大模型的稳定连接。

weixin_29205061的博客 310

二分图之匈牙利算法

主要内容:二分图的最大匹配,完美匹配,最小路径覆盖数,匈牙利算法 二分图相关概念1.二分图:把一个图的顶点划分为两个不相交集U和V,使每一条边都分别连接U、V中的顶点。 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。即是说,一个图要么没有环,要么有偶数边的环。所以二分图的另一个定义为:不含有「含奇数条边的环」的图。 2.匹配:在图论中,一个「匹配」(match

ROOM 862

Ansys -PEmag 平面变压器仿真与circuit电路模型验证

ansys 软件集成了电路、磁路、PCB参数提取,结构参数提取等功能仿真,基于内置模块的功能参数的仿真后可以提取出主要关键参数,寄生参数,频域响应参数等。该软件的优势在于能够将所有的仿真参数导出为电路模型文件,可以在自带的模块中仿真也可以导出在其他第三方软件中仿真,比如matlab-simulink文件扥。主要介绍ANSYS插件的使用,对PEmag做了详细使用说明并通过案例得到对用的变压器参数;基于变压器参数再将其磁路模型导入到电路中进行建模仿真,实现PEmag与circuit的联合仿真。

weixin_41609745的博客 3016

ArcGIS利用模型构建器批量导出nc文件中的不同波段数据

ArcGIS利用模型构建器批量导出nc文件中的不同波段数据

Yuanbaokk的博客 7253

二部图------KM算法、匈牙利算法

二分图的概念 二分图又称作二部图,是图论中的一种特殊模型。  设G=(V, E)是一个无向图。如果顶点集V可分割为两个互不相交的子集X和Y,并且图中每条边连接的两个顶点一个在X中,另一个在Y中,则称图G为二分图。  二分图的性质 定理:当且仅当无向图G的每一个回路的次数均是偶数时,G才是一个二分图。如果无回路,相当于任一回路的次数为0,故也视为二分图。 二分图匹配 给定一个二分图G,在...

wang_gongzi的博客 1958

嵌入式代码审计中常见的漏洞(四)

经过漫长时间的迭代更新,内容从一开始的碎片化网罗搜集,到排版与整合划分,再到学习与实践验证,最后摒弃初始,用自己的语言与实践结论通俗的将它展现出来。强化知识技能的同时也为读者带来更好的阅读体验。 本篇介绍了以下代码安全问题: 编号 漏洞 1 敏感信息硬编码 2 未初始化安全 3 越界访问 4 迭代器失效 5 迭代器尾部解引用

武天旭的博客 3317

二分图匹配-匈牙利算法

二分图概述 所谓二分图,就是我们可以将图中所有的点分为A、B两个集合,从而使得集合内部任意两个点都不直接相连。 二分图适用于解决一种类似于婚姻匹配的问题,即如果A-B匹配,那么A就不能在和C匹配,即便他们之间有好感。 最大匹配 二分图的最大匹配即需要给出一种分配策略,使得产生尽可能多的对(就是撮合最多多少对情侣)。 匈牙利算法是一个用于解决该类问题的标准算法之一,核心想法是让路:假设你(就是红娘)当前想撮合Bi与Gk,但是Gk已经有了对象Bj,此时红娘就和Bj交涉能否让Bj尝试换一个对象.

The Shawshank Redemption 6543

【GameFramework框架】7-2、GameFramework框架是否“过度设计”?

框架是否过度设计,这个问题其实我被问到很多次了。不仅仅是新手刚接触就觉得“过度设计”的评价,有些熟练的开发者也会有这种感觉。那么,这篇文章就来探究一下,为什么框架会让人感觉“过度设计”,以及框架如何设计,还有,如何让框架适应自己的节奏。

优快云博客专家,Unity3D高级软件工程师,《Unity 3D从入门到实战》作者。 2118

【K210+STM32项目】基于K210与STM32协同工作的智能垃圾分类系统设计与实现(更新3.0版本)(完整工程资料源码)

STM32F407STM32F407_2(含有app功能)

嵌入式技术开发 2489

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

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。 基本原则就是在原有匹配(最开始的按优先顺序匹配)基础上重新分配,看是否可以添加一个新的匹配。 预备知识 我们需要了解一下图论的一些知识。 1 无向图 边没有方向的图称为无向图...

Young_Fan 1万+

Coze智能体开发:工作流教程之解析文件概述

大模型本身并不具备文件读取和解析的能力,无法直接处理文件字节流。对于支持工具调用(Function calling)的模型,扣子提供插件功能来帮助大模型调用外部工具 API,拓展大模型的能力边界。扣子插件商店提供海量官方插件和第三方插件,例如链接读取插件可以将链接对应的文件内容解析为纯文本传递给大模型。

王国平的博客 1793

使用matlab对二部图进行匹配(匈牙利算法)

使用matlab应用匈牙利算法对二部图进行匹配。 算法的代码主体来自知乎用户洪九(李戈)的专栏文章策略算法工程师之路-图优化算法(一)(二分图&最小费用最大流) 具体算法思想文章里和其它地方都有,不在这里赘述。主要通过例子来说明算法具体运行过程中所作的操作对匈牙利算法进行说明。 首先对于如下图的一个二部图 左侧有6个点,右侧有7个点,点之间的边都画出来了。 第一步:对x1x_1x1​进行匹配,找到它的第一个可匹配项y1y_1y1​,发现此时y1y_1y1​还未被匹配,因此将x1x_1x1​和y1y

john_xia的博客 4556

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

匈牙利算法求二部图的最大匹配

匈牙利算法求二部图的最大匹配(含详细算法步骤) 1.概念 (1)二部图(偶图) (2)匹配 (4)饱和 (5)可增广路 (6)匈牙利算法 2.数学语言表示匈牙利算法 (1)算法流程 (2)举例

weixin_69884785的博客 2039

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

二部图匹配-匈牙利算法-KM算法

int M, N; //M, N分别表示左、右侧集合的元素数量 int Map[MAXM][MAXN]; //邻接矩阵存图 int p[MAXN]; //记录当前右侧元素所对应的左侧元素 bool vis[MAXN]; //记录右侧元素是否已被访问过 bool match(int i) { for (int j = 1; j <= N; ++j) if (Map[i][j] && !vis[j]) //有边且未访.

己亥孟陬 900

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

【数学与算法】二部图、匈牙利匹配、稳定婚配

14.1 二部图 广度优先搜索 广度优先,可以使用队列来操作,依次遍历节点,首先遍历节点A,判断节点A是否遍历过,如果节点A没有遍历过,就把节点A添加进队列。然后取出队列中的第一个元素A,对于和节点A连接的某节点B和节点C等,把节点B和c进行标记(标记就是根据题目的具体要求进行操作,即你的目的是什么你就干什么),并且如果节点B和c没有遍历过,那么把节点B和C添加进队列。然后再取出队列中的第一个元素,就是节点B,遍历到了B节点,再对和B节点连接的节点D进行标记,并且判断D是否遍历过,没有遍历过的话就添加到队列

u011754972的博客 1330

Python-匈牙利算法求二部图的最大匹配

hyi asc from collections import defaultdict import time class Graph: def __init__(self,n,s,t,l) -> None: self.S,self.T,self.L=s,t,l # 源s,汇t self.edge=defaultdict(list) # 边集 self.ver_high=[0 for i in range(n)] # 每个顶点的高度

qq_37217601的博客 898

记录下HDU-2063(二部图-匈牙利算法)

二部图例题HDU-2063(匈牙利算法) 二部图基本概念: 二部图:一个图中的所有点能够被划分为两个集合,图中的所有边都跨越了集合的边界。(例如:一群人以男女区分为两部分,一些男生喜欢一些女生,一些女生喜欢一些男生,这些男女生和这些喜欢的情况可以称作二部图) 匹配:匹配是一组边的集合,其中任意两边都没有公共点。(若彼此喜欢男女生能够在一起,某一情况下所有这种能够在一起的关系称为匹配,这一情况下在一起的关系就称为匹配边,原本喜欢但是没有在一起的就称为未匹配边) 最大匹配:所有匹配中,边数最多的一个匹配关系。

weixin_47350566的博客 390

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

#define MAXN 10 //MAXN为表示X集合和Y集合顶点个数最大值的符号常量 int nx, ny; //X和Y集合中顶点的个数 int g[MAXN][MAXN]; //邻接矩阵,g[i][j]为1表示Xi和Yj有边相连 int cx[MAXN] , cy[MAXN]; //cx[i]表示最终求得的最大匹配中与Xi匹配的Y顶...

Phoebe_Wu2016的博客 333

【二部图匹配问题--匈牙利算法】

最近的研究需要,学习二部图的匹配问题,自然就学习了匈牙利算法,虽然跟我目前要解决的问题--多对多加权双边匹配问题有许多不同,但算是二部图匹配的入门算法。 在网上看到不错的博文,借来学习。 http://blog.youkuaiyun.com/pi9nc/article/details/11848327该博文基本概念讲得不错匈牙利算法(二部图匹配、已知各个节点的偏好集合、无权匹配、一对一、最大化所有匹配边数...

weixin_30412167的博客 343

【PTA数据结构 | C语言版】求解二部图最大匹配的匈牙利算法

请编写程序,实现求解无权二部图最大匹配的匈牙利算法。输入格式:输入首先在第一行给出 3 个正整数,依次为二部图 G=(U∪V,E) 中 U 点集顶点数、V 点集顶点数(均不超过 100)和边数 m。随后 m 行,每行给出一条连接 U 点集顶点和 V 点集顶点的边,格式为 u v,其中 u 属于 U,v 属于 V。两个点集的顶点编号均从 0 开始。同行数字间以一个空格分隔。输出格式:在一行中输出 最大匹配值 = x,其中 x 为最大匹配数。

等风来 682

二部图匹配匈牙利算法(转)

这种题目一般是一个东东对应着另外的东东,一般是多对多的关系,这就形成了一个二部图,问这个二部图最大的匹配数是多少(就是形成一个一对一的关系,求最大的一对一关系的个数)。模板:#define MAXN 310int nx,ny,mat[MAXN][MAXN],fy[MAXN],matx[MAXN],maty[MAXN];int path(int u) {int v;for (v=

1635

二部图-匈牙利算法实现

两篇参考网址 http://blog.youkuaiyun.com/dark_scope/article/details/8880547 相亲举例http://m.blog.youkuaiyun.com/blog/fyxz1314/37651567 偏公式 增广路径:非匹配边->匹配边->非匹配边组成的路径递归:将之前匹配边的女生赋给新的男生,之前匹配边的男生重新找到心仪的女生,如此递归。 #include

相门码农的专栏 732

二部图 匈牙利算法

匈牙利算法:http://www.renfei.org/blog/bipartite-matching.html  http://www.codeceo.com/article/bgraph-match-algorithm.html http://dsqiu.iteye.com/blog/1689505 一道练习题: http://blog.sina.com.cn/s/blog_ac

lnlnlnying的博客 482
上一篇: 最小树形图(有向图的最小生成树)
下一篇: 打印月历
softwareX4
博客等级 码龄9年 21粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值