匈牙利算法 二分图

匈牙利算法求二分图的最大匹配 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 二分图的最大匹配: 匈牙利算法  完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。  最小覆盖: 最小覆盖要求用最少 阅读详情

  这几个图和定义转自https://www.byvoid.com/blog/hungary/

 未盖点:设Vi是图G的一个顶点,如果Vi 不与任意一条属于匹配M的边相关联,就称Vi 是一个未盖点。

交错路:设P是图G的一条路,如果P的任意两条相邻的边一定是一条属于M而另一条不属于M,就称P是一条交错路。

可增广路:两个端点都是未盖点的交错路叫做可增广路。

 

  匈牙利算法是用来求最大匹配数的,主要就是找增广路,增广路其实就是虚边-实边-虚边-实边...-虚边这个样子,第一条和最后一条都是虚的,实边连的两个点就是配对的,找增广路就是再找一个不在M中的点,看能不能把路变长或者找到一条匹配的新边。

  有两组x,y,用cx,cy数组分别记录x组的节点匹配情况和y组节点匹配情况(cx[i]=j就是x组的第i个点和y组的第j个点匹配,如果没匹配为0)

int augment_path(int u)
{
    int v;
    for(v=1; v<=q; v++)
        if(edge[u][v]&&!vis[v])
        {
            vis[v]=1;
            if(!cy[v]||augment_path(cy[v])) //如果v没匹配或者从v本来对应的x组中的点找到了增广路,u就可以和v匹配
            {
                cx[u]=v;
                cy[v]=u;
                return 1;
            }
        }
    return 0;
}
void hungary()
{
    memset(cx,0,sizeof(cx));
    memset(cy,0,sizeof(cy));
    int i;
    for(i=1; i<=p; i++)
        if(!cx[i])  //如果有未匹配的节点,看能不能从这个点开始找到增广路
        {
            memset(vis,0,sizeof(vis));
            if(augment_path(i)) ans++;
        }
}


A - Chessboard
Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u

Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of cards with size 1 * 2 to cover the board. However, she thinks it too easy to bob, so she makes some holes on the board (as shown in the figure below).

We call a grid, which doesn’t contain a hole, a normal grid. Bob has to follow the rules below:
1. Any normal grid should be covered with exactly one card.
2. One card should cover exactly 2 normal adjacent grids.

Some examples are given in the figures below:

A VALID solution.


An invalid solution, because the hole of red color is covered with a card.


An invalid solution, because there exists a grid, which is not covered.

Your task is to help Bob to decide whether or not the chessboard can be covered according to the rules above.

Input

There are 3 integers in the first line: m, n, k (0 < m, n <= 32, 0 <= K < m * n), the number of rows, column and holes. In the next k lines, there is a pair of integers (x, y) in each line, which represents a hole in the y-th row, the x-th column.

Output

If the board can be covered, output "YES". Otherwise, output "NO".

Sample Input

4 3 2
2 1
3 3

Sample Output

YES

  这种棋盘覆盖问题就可以转化为二分图问题了,把棋盘上的相邻的点分为两组,求最大匹配数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#define INF 0x3f3f3f3f
int M,N,K;
int ans,p,q;
int a[50][50],vis[1000],map[50][50],cx[1000],cy[1000],edge[1000][1000];
int move[4][2]= {-1,0,0,-1,0,1,1,0};
int augment_path(int u)
{
    int v;
    for(v=1; v<=q; v++)
        if(edge[u][v]&&!vis[v])
        {
            vis[v]=1;
            if(!cy[v]||augment_path(cy[v]))
            {
                cx[u]=v;
                cy[v]=u;
                return 1;
            }
        }
    return 0;
}
void hungary()
{
    memset(cx,0,sizeof(cx));
    memset(cy,0,sizeof(cy));
    int i;
    for(i=1; i<=p; i++)
        if(!cx[i])  
        {
            memset(vis,0,sizeof(vis));
            if(augment_path(i)) ans++;
        }
}
int main()
{
    while(scanf("%d%d%d",&M,&N,&K)!=EOF)
    {
        int i,j,k,m,n,x,y;
        ans=0;
        p=0;
        q=0;
        memset(map,0,sizeof(map));
        memset(a,0,sizeof(a));
        for(i=1; i<=K; i++)
        {
            scanf("%d%d",&m,&n);
            map[n][m]=1;
        }
        for(i=1; i<=M; i++)
            for(j=1; j<=N; j++)
            {
                if((i+j)%2==0) a[i][j]=++p;
                else a[i][j]=++q;
            }
        for(i=1; i<=M; i++)
            for(j=1; j<=N; j++)
                if((i+j)%2==0&&!map[i][j])
                    for(k=0; k<4; k++)
                    {
                        x=i+move[k][0];
                        y=j+move[k][1];
                        if(x>0&&x<=M&&y>0&&y<=N&&!map[x][y])
                        {
                            edge[a[i][j]][a[x][y]]=1;
                        }
                    }
        hungary();
        if(ans*2+K==M*N)
            printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}


[ 二分图匹配 ] 匈牙利算法 和 KM算法 总结 前言:高中时候老师讲这个就听得迷迷糊糊,有一晚花了通宵看KM的Pascal代码,大概知道过程了,后来老师说不是重点,所以忘的差不多了。都知道二分图匹配是个难点,我这周花了些时间研究了一下这两个算法,总结一下1. 基本概念 M代表匹配集合 未盖点:不与任何一条属于M的边相连的点交错轨:属于M的边与不属于M的边交替出现的轨(链)可增广轨:两端点是未盖点的交错轨  阅读详情

相关推荐

二分图匹配——匈牙利算法の板子

ATP终于写完了人生第一篇学习笔记▽

ADP+Pi==ATP 1680

二分图——棋盘覆盖(匈牙利算法的应用)

白色的是偶数格,黑色的是奇数格,可以发现,白色格子四个方向都是黑色格,黑色格子四个方向都是白色格子。满足了对于划分的两个集合中任意一个,同一个集合内没有边的要求。有了边之后就要把边的两个端点划分成两个集合,这里可以把行号和列号加起来是偶数的格子看成集合1,加起来是奇数的看成集合2。在里面,有一个任意两张骨牌都不重叠,与要素2相对应,每一个骨牌都是由两个相邻方格构成,可以将骨牌看成一条边连接了两个方格。1.节点能分成两个独立的集合,每个集合内部没有边互相连接。2.每一个节点只能与另一个集合有一条匹配边相连。

测试 734

二分图算法及其应用:从匹配问题到匈牙利算法实战

二分图是图论中的一种特殊图,它广泛应用于网络流、优化问题等领域。本章将从二分图的基本概念、性质和判定方法等角度进行详细解读。匈牙利算法(Hungarian algorithm),由Harold Kuhn和James Munkres提出,是一类在图论中寻找二分图最大匹配的有效算法。该算法广泛应用于各种分配问题,如婚姻问题、工作分配问题等,它为解决这类问题提供了一种有效的数学模型和解决方案。构建初始匹配是匈牙利算法的第一步。这通常涉及到寻找一个完美匹配,或是找到一个尽量大的匹配。

weixin_32747681的博客 1432

二分图匹配

二分图是一种特殊的图 对于无向图G=(V,E),如果V可以分为两个互不相交的子集(X,Y),并且图中的每条边所依附的两点属于不同的子集,则图G则称为一个二分图。边的描述: e={x,y} x来自G的顶点集X,y来自G的顶点集Y定理:一个无向图G=(V,E)是二分图当且仅当G中无奇数长度的回路。二分图匹配:给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是

wyk19950704的博客 1011

抖音直播参数逆向实战:手把手教你用Python获取ttwid和x-bogus(附完整代码)

本文深入解析抖音直播接口的反爬机制,重点剖析核心防护参数ttwid和x-bogus的生成原理与作用。通过Python实战,手把手教你逆向获取ttwid、webid等关键参数,并构建稳定的数据采集方案,为开发者提供企业级数据获取能力。

weixin_29196891的博客 1043

cuda安装时出现错误 Unable to locate package cuda-toolkit-12-4

cuda安装时出现错误 Unable to locate package cuda-toolkit-12-4

4865

一般图的最大匹配问题(真心觉得难)

概念分析: 未盖点:设Vi是 图G 的一个顶点,如果Vi 不与任意一条(属于匹配M)的边相关联,就称Vi 是一个未盖点。简言之,点不在匹配边的两端。 交错路:设P是 图G 的一条路,如果P的任意两条相邻的边一定是一条属于M而另一条不属于M,就称P是一条交错路。简言之,一条匹配边,一条非匹配边,交错。 可增广路:(两个端点都是未盖点的)交错路叫做可增广路。简言之,就是非

harbour的专栏 5443

python特征选择pso_【来点干货】机器学习中常用的特征选择方法及非常详细的Python实例...

花费了很长时间整理编辑,转载请联系作者授权,违者必究。特征选择(Feature selection)是在构建预测模型的过程中减少输入变量的一个过程。它是机器学习中非常重要的一步并在很大程度上可以提高模型预测精度。这里我总结了一些机器学习中常见的比较有用的特征选择方法并附上相关python实现code。希望可以给大家一些启发。首先,我们为什么要进行特征选择呢?它有以下几个优点:减少过拟合:冗余数据常...

weixin_39927158的博客 1161

棋盘覆盖(二分图匹配)

思路:

Ray.C.L的博客 566

美团mtgsig 3.1.0算法还原:从加密入口到d1生成的完整链路拆解

本文详细拆解了美团mtgsig 3.1.0签名算法的完整逆向过程。通过定位加密入口函数eH,理清a6、a5、a8到d1的生成依赖链,并运用插桩技术,在JSVMP混淆环境下逐步还原了核心参数的生成逻辑,为逆向工程实践提供了清晰的纯算还原方法论。

oo7890的博客 776

基于Playwright+Pytest+Yaml+Allure的UI自动化测试框架实战指南

本文详细介绍了基于Playwright+Pytest+Yaml+Allure的UI自动化测试框架实战指南,涵盖环境搭建、核心功能实现及高级技巧。通过数据驱动测试、页面操作封装和智能等待机制,提升测试效率与可维护性。Allure报告增强功能为团队提供直观的质量反馈,助力高效UI自动化测试。

weixin_28826521的博客 488

二部图,最大匹配

合肥网赛有道题说是用二分匹配来做,于是决定好好看看二分匹配。荡了好久算是看明白了。帖子转自ycool什么是二分图,什么是二分图的最大匹配,这些定义我就不讲了,网上随便都找得到。二分图的最大匹配有两种求法,第 一种是最大流(我在此假设读者已有网络流的知识);第二种就是我现在要讲的匈牙利算法。这个算法说白了就是最大流的算法,但是它跟据二分图匹配这个问题的 特点,把最大流算法做了简化,提

遇见_缘 2538

自动驾驶大模型---小鹏汽车VLA大模型

随着自动驾驶技术的进步,小鹏汽车正通过云端大模型蒸馏技术,将72B参数的VLA大模型轻量化后部署到车端,以提升自动驾驶系统的智能和安全性。这种技术路线不仅解决了“模态不统一”的问题,还通过强化学习增强了模型的表现。

智能汽车人的博客 2235

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

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

Young_Fan 1万+

Python 爬虫实战:豆瓣 / IMDB 电影数据抓取(评分 + 剧情 + 演员阵容结构化处理)

在数据为王的时代,电影数据是进行市场分析、推荐系统构建和学术研究的重要资源。豆瓣和 IMDB 作为国内外最具影响力的电影评分和资讯网站,包含了海量高质量的电影数据。本文将带领你从零开始,构建一个健壮的 Python 爬虫,用于抓取豆瓣和 IMDB 的电影信息,并将其中的非结构化数据(如剧情简介、演员列表)进行清洗和结构化处理,最终存储到便于分析的结构化文件(如 CSV)中。

yansideyucsdn的博客 953

基于FPGA的时间数字转换(TDC)设计(一:原理)

基于FPGA的时间数字转换(TDC)设计,此为第一篇

sdau2005的博客 5069

二分图完全匹配算法之匈牙利算法

最近在参加了一个小项目,里面用到二分图匹配算法,因为之前并没有接触过相关算法,于是找到一些博客进行了一番学习,但学习之后,发现部分博客或多或少存在一些另我疑惑的地方,于是,我打算写此博客以巩固对算法的理解。 一、二分图基本概念 二分图(Bipartite graph)又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图

小菜鸡的博客 6932

VC中sqlite的使用

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

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

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

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

二分图匹配-匈牙利算法

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

The Shawshank Redemption 6543

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

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

二分图简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。 也就是说,把一个图的顶点划分为两个不相交集 XX 和 YY ,使得每一条边都分别连接XX 、YY 中的顶点。如果存在这样的划分,则此图为一个二分图。二分图的一个等价定义是:不含有「奇数条边的环」的图。图11不含有「奇数条边的环」我们习惯上将其画成下列形式:可以看到图22中每条边的两个端点属于不同的集合

六天 1万+

二分图——匈牙利算法

二分图的基本概念 一个无向图G=,如果存在两个集合X、Y,使得X∪Y=V, X∩Y=Φ,并且每一条边e={x,y}有x∈X,y∈Y,则称G为一个二分图(bipartite graph)。常用<X, E, Y>来表示一个二分图。若对X中任一x及Y中任一y恰有一边e∈E,使e = {x, y}, 则称G为完全二分图(complete bipartite graph)。当|X| = m,|Y| = n时

Roly 1019

二分图、匈牙利算法

完全二分图是一种特殊的二分图,可以把图中的顶点分成两个集合,使得第一个集合中的所有顶点都与第二个集合中的所有顶点相连。很显然,主要的效率问题就是,在唯一的while循环里面,有1个从1到n的循环,只为了检索一些特定的目标出来。题目大意就是把图分成二分图,如果不能的话,输出-1,如果能的话,分别输出2个部分的点的数量和点的标号。二分图是指,可以把图中的顶点分成两个集合,使得每个集合中的所有点之间都是互不相连的。表面上有3层循环,实际上外面的2层while循环是有限制的,合起来也就是大约n而已。

nameofcsdn的博客 1323

二分图——匈牙利算法——的学习

什么是二分图: 二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V,E 可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 ...

T.J的博客 360

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

什么是匹配 匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点。 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。 二分图的匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。 二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。 匈牙利算法 前面的染色法是判断一个图是否是二分图; 匈牙利算法就是在是二分图的基础上,求二分图的最大匹配的算法。 二分图

HangHug_L的博客 987

二分图—匈牙利算法

转载自 http://www.renfei.org/blog/bipartite-matching.html 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm);不讲带权二分图的最佳匹配。 二分

小小码农 868
上一篇: poj3254 poj1185 状态压缩DP
下一篇: 勾股数公式
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值