说到二分,我们就很容易想到二分查找算法,今年下半年……,今天所介绍的二分图和二分查找没有太大的联系,我们先来看一下它的定义:

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

通俗一点说,就是把象棋盘开局时上的红子(集合A)和黑子(集合B)互相连线,红黑不同(A∩B=∅),而且连线双方都是不同的势力(分别属于两个集合),像这样的就叫二分图。

一般来说这种图长这样:

可以清晰地看出左右的顶点构成了两个相互独立的集合,而且这是单向图

一般来说,对于这种图像需要面对的问题,大多是匹配问题,即两个点集A,B可以两两结合出多少种组合,二分图的最大匹配就是研究他们之间的组合的最大个数,下边介绍一种算法来解决这个问题。

匈牙利算法

百度百科上相关介绍:

匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法。美国数学家哈罗德·库恩于1955年提出该算法。此算法之所以被称作匈牙利算法,是因为算法很大一部分是基于以前匈牙利数学家Dénes Kőnig和Jenő Egerváry的工作之上创建起来的。

依托上图(设左点集为集合A,右点集为集合B,连接两个集合的线段均为从A指向B),介绍一下这种算法的思路。

  1. 首先根据输入确定集合点之间的对应关系(比如集合A的1点可与B中的5,7点对应,类似于映射),这需要一个二维数组relationships[amount1][amount2]来储存,(比如relationships[1][5]=1,relationships[1][6]=1)类似于邻接矩阵的建立,但是不同的是二分图是单向图,只需要建立朝向一个方向的向量即可。
  2. 对指向集合中的每一个点进行递归搜索(例如上图集合A中的所有点).
  3. 在递归搜索中,以当前点current的视角,对B集合所有点进行逐一访问(比如说图上A1对B5,B6,B7,B8进行访问),若满足relationships[current][Bi]=1,且Bi在current点的这轮访问中没有被访问过,那么执行下一步.
  4. 若Bi点当前没有匹配对象(单身),或者令Bi现有的匹配对象更改匹配可行(修罗场)  (比如说A2逐一访问B5时强制令A1点继续向下访问,由于条件满足,A1与B7配对。),那么Bi的匹配对象就是current点.

其中递归搜索(dfs)的代码的一个形式如下:

int relationships[500][500],partners[500];//关系数组,匹配对象数组。
bool vis[500];//标记在一轮搜索中已经被访问的点。
int dfs(int current)//需要返回值,不能为void型
{for(int i=1;i<=Bmax;i++)//Bmax为B集合最大点数.{if(relationships[current][i]&&!vis[i]){vis[i]=1;//这个点在这一轮中被访问过了,以防下面的递归无限访问造成死循环。if(!partners[i]||dfs(partners[i]))//如果i点没有匹配对象,或者i点可以有其他选择.{  partners[i]=current;return 1;   //匹配成功}}}return 0;
}//在主函数里...for(int i=1;i<=Amax;i++)//Amax为A集合最大点数
{memset(vis,0,sizeof(vis));//由于vis数组是用来标记一轮搜索中被访问的点的,所以一轮搜索结束后要重置。dfs(i);//每个点都要搜索一遍
}

下面看一道例题:HDU2063

过山车

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 31700    Accepted Submission(s): 13647

Problem Description

RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了。可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个男生做partner和她同坐。但是,每个女孩都有各自的想法,举个例子把,Rabbit只愿意和XHD或PQK做partner,Grass只愿意和linle或LL做partner,PrincessSnow愿意和水域浪子或伪酷儿做partner。考虑到经费问题,boss刘决定只让找到partner的人去坐过山车,其他的人,嘿嘿,就站在下面看着吧。聪明的Acmer,你可以帮忙算算最多有多少对组合可以坐上过山车吗?

Input

输入数据的第一行是三个整数K , M , N,分别表示可能的组合数目,女生的人数,男生的人数。0<K<=1000
1<=N 和M<=500.接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。最后一个0结束输入。

Output

对于每组数据,输出一个整数,表示可以坐上过山车的最多组合数。

Sample Input

 

6 3 3 1 1 1 2 1 3 2 1 2 3 3 1 0

Sample Output

 

3

由于男生和女生之间为两个独立集合,并且女生集合中的元素单方向指向了男生集合的元素。这是显然的二分图匹配。

附上AC代码:

//Battlefield control establishing....
#include <iostream>
//#include <bits/stdc++.h>
#include <cstdio>
#include <iomanip>
#include <cstring>
//#include <minmax.h>
#define MCV main
#define read(a) scanf("%lld",&a)
#define reset(a,b) memset(a,b,sizeof(a))
const int INF=0x3f3f3f3f;
typedef long double ld;
typedef long long ll;
using namespace std;
//Get ready?LET'S ROCK!
bool vis[10005];
int rel[1000][1000],fb[1000];
int k,m,n;
int dfs(int cur)
{for(int i=1;i<=n;i++){if(rel[cur][i]&&!vis[i]){vis[i]=true;if(!fb[i]||dfs(fb[i])){fb[i]=cur;return 1;}}}return 0;
}
int MCV()
{while(cin>>k&&k){reset(rel,0);reset(fb,0);cin>>m>>n;int tmp1,tmp2;for(int i=1; i<=k; i++){cin>>tmp1>>tmp2;rel[tmp1][tmp2]=1;}int ans=0;for(int i=1; i<=m; i++){reset(vis,false);ans+=dfs(i);}cout<<ans<<endl;}return 0;
}

二分图匹配-匈牙利算法相关推荐

  1. nyoj-239 月老的难题 (二分图匹配—匈牙利算法 网络流—Dinic算法)

    月老的难题 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...

  2. 二分图匹配--匈牙利算法

    文章目录 二分图: 匹配 匈牙利算法 代码: 二分图: 二分图是一个无向图,点集分成子集X和Y,图中每一条边都是一边在X一边在Y 当且仅当无向图G的每一个回路次数都是偶数时(包括0),G就是一个二分图 ...

  3. 二分图匹配匈牙利算法DFS实现

    1 /*==================================================*\ 2 | 二分图匹配(匈牙利算法DFS 实现) 3 | INIT: g[][]邻接矩阵; ...

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

    匈牙利算法 什么是匈牙利算法 匈牙利算法是一种在多项式时间内求解任务分配问题的组合优化算法,并推动了后来的原始对偶方法.美国数学家哈罗德·库恩于1955年提出该算法.此算法之所以被称作匈牙利算法,是因 ...

  5. Codevs 1222 信与信封问题 二分图匹配,匈牙利算法

    题目: http://codevs.cn/problem/1222/ 1222 信与信封问题   时间限制: 1 s   空间限制: 128000 KB   题目等级 : 钻石 Diamond 题解 ...

  6. HDU 2063 过山车 二分图匹配 匈牙利算法

    过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submis ...

  7. 二分图匹配----匈牙利算法之二

    poj 1469 COURSES //题意:现在有p门课程和n个学生,现在需要有由p个学生组成的组织,该组织满足每个学生代表一门课程以及每门课程只能由一个学生代表, //现给出每门课程都有哪些学生可以 ...

  8. 【CF1139E】Maximize Mex - 二分图匹配 - 匈牙利算法

    [题目链接] https://www.luogu.com.cn/problem/CF1139E [题目描述] 有n个学生,第i个学生在俱乐部c_i,并拥有一个能力值a_i.在接下来的d天中,每天会有一 ...

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

    什么是匹配 匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点. 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配. 二分图的匹配:给定一个二分图G,在G ...

最新文章

  1. C++11中头文件atomic的使用
  2. 无限互联新浪微博项目(视频)分享
  3. “治沙女杰”殷玉珍:和沙漠较量的女人
  4. Jenkins + OSChina CI 最简
  5. 从unmarshal带json字符串字段的json说起
  6. 前端要懂mysql_【灵魂拷问】你真的懂得Mysql的管理和使用吗?
  7. 将 Smart 构件发布到 Maven 中央仓库
  8. python一般用什么编译器-Python必学之编译器用哪个好?你用错了吧!
  9. Uipath 学习栏目基础教学:1Uipath设计器介绍
  10. `>>`(有符号右移) 和 `>>>`(无符号右移)的区别
  11. mysql数据库删除一条数据后还想让新增数据从空缺id处开始
  12. windows 快捷键整理
  13. 庆贺使用VS2017编译OpenJDK12成功!
  14. spss 25 的pls安装
  15. c语言四个人中有一个人是小偷,涛涛学BASIC逻辑判断
  16. 运维工程师和网络工程师的差别在哪?到底哪个更有“钱”途?
  17. args 打印输出argparse.ArgumentParser()的所有选项和默认值
  18. OWASP ZAP 扫描漏洞误报分析
  19. iOS 自动续期订阅,订阅升级降级、订阅时间、退收费处理
  20. 小米 11 的重点,和充电器无关

热门文章

  1. webpack是什么?有什么用?
  2. 《Set》Java中的Set用法(详细整理)
  3. Pytorch使用GPU计算
  4. 深度之眼Pytorch打卡(九):Pytorch数据预处理——预处理过程与数据标准化(transforms过程、Normalize原理、常用数据集均值标准差与数据集均值标准差计算)
  5. Centos 安装阿里云yum源和EPEL源
  6. VMware之usb识别不了(灰色)的问题解决办法
  7. 利用vite插件开发,实现工程化打包,建议收藏
  8. 2019年头条笔试题大锤升职
  9. 顶级AI软件开发工具总结
  10. 华为鸿蒙手机参数,华为鸿蒙首批升级机型名单曝光:双系列手机、折叠屏和平板电脑...