今天开始继续学习啦~


二分图

二分图也称为二部图,定义如下:
设无向图G=<V,E>,若能将V划分成V1,V2两个独立的顶点集(V1交V2为空,V1并V2为G,且V1,V2非空),使得G中每条边的两个端点皆是一个属于V1,另一个属于V2,则称G为二分图(二部图),V1,V2为互补的顶点子集,常将二部图G记作<V1,V2,E>
若G是简单二分图,V1中的每个顶点均与V2中的所有顶点相邻,称G为完全二部图,记为Kr,s 其中r=|V1|,s=|V2|
n阶零图 (n>=2) 是二分图

定理:n阶无向图G是二分图当且仅当G中无奇圈

匹配

匹配:一个匹配是一个边的集合,集合里面的任意两条边都没有公共顶点
最大匹配:最大匹配即含边数最多的匹配
完美匹配:一个图中所有顶点皆为匹配点,则称其为一个完美匹配
交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路
增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路。增广路径有以下性质(设图为G,P为两个未匹配点之间的路径,M为已匹配的边集:
(1)P的路径个数必定为奇数,第一条边和最后一条边都不属于M。
(2)将M和P进行取反操作可以得到一个更大的匹配
(3)M为G的最大匹配当且仅当不存在M的增广路径

匈牙利算法

算法描述:设图为G,P为两个未匹配点之间的路径,M为已匹配的边集
1.首先置M为空
2.找增广路径P,再进行异或操作得到更大的匹配
3.重复第2步直到找不出增广路径为止

算法模板

#include<iostream>
#include<string>
#include<string.h>
//description: this is a program for algorithm-Hungarian
const int MAXN = 101;
using std::string;
//
int n1,n2;//vertexes
int m;//edge
int Matrix[MAXN][MAXN];//Graph
int Visited[MAXN];//sign
int Match[MAXN];//indicate match
//
int DFS(int x)
{for(int i=1;i<=n1;i++){if(!Visited[i]&&Matrix[x][i])//judge unvisited & matchable{Visited[i]=1;if(Match[i]==0||DFS(Match[i]))//judge (unmatched) or (have to change match point){Match[i]=x;return 1;//match successful}}}return 0;
}//Hungarian Algorithm
//
int main()
{memset(Match,0,sizeof(Match));while(std::cin>>m>>n1>>n2){memset(Matrix,0,sizeof(Matrix));int count=0;int row;int col;//axisfor(int i=1;i<=m;i++){std::cin>>row>>col;Matrix[row][col]=1;//connect}//Hungarianfor(int i=1;i<=n2;i++){memset(Visited,0,sizeof(Visited));if(DFS(i)){count++;}}//std::cout<<"output:"<<count<<std::endl;//output}return 0;
}

一般最大匹配的结果可能不止一种,所以大多数题目应该是输出最大匹配数


题目:

P2756 飞行员问题

英国皇家空军从沦陷国征募了大量外籍飞行员。由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外籍飞行员。在众多的飞行员中,每一名外籍飞行员都可以与其他若干名英国飞行员很好地配合。如何选择配对飞行的飞行员才能使一次派出最多的飞机。对于给定的外籍飞行员与英国飞行员的配合情况,试设计一个算法找出最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。
对于给定的外籍飞行员与英国飞行员的配合情况,编程找出一个最佳飞行员配对方案,使皇家空军一次能派出最多的飞机。

输入
第 1 行有 2 个正整数 m 和 n。n 是皇家空军的飞行员总数(n<100);m 是外籍飞行员数(m<=n)。外籍飞行员编号为 1~m;英国飞行员编号为 m+1~n。
接下来每行有 2 个正整数 i 和 j,表示外籍飞行员 i 可以和英国飞行员 j 配合。最后以 2个-1 结束。

输出
第 1 行是最佳飞行员配对方案一次能派出的最多的飞机数 M。接下来 M 行是最佳飞行员配对方案。每行有 2个正整数 i 和 j,表示在最佳飞行员配对方案中,飞行员 i 和飞行员 j 配对。如果所求的最佳飞行员配对方案不存在,则输出‘No Solution!’。

把模板输入输出改一下,再输出Match矩阵就行了,注意,由于要输出匹配,DFS内i要从最大值开始减小。

#include<iostream>
#include<string>
#include<string.h>
//description: this is a program for algorithm-Hungarian
const int MAXN = 101;
using std::string;
//
int n1,n2;//vertexes
int m;
int Matrix[MAXN][MAXN];//Graph
int Visited[MAXN];//sign
int Match[MAXN];//indicate match
//
void print()
{for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){std::cout<<Matrix[i][j]<<" ";}std::cout<<"\n";}
}
int Hungarian(int x)
{for(int i=m;i>n2;i--){if(!Visited[i]&&Matrix[x][i])//judge unvisited & matchable{Visited[i]=1;if(Match[i]==0||Hungarian(Match[i]))//judge (unmatched) or (have to change match point){Match[i]=x;return 1;//match successful}}}return 0;
}//Hungarian Algorithm
//
int main()
{memset(Match,0,sizeof(Match));if(std::cin>>n1>>m){n2=m-n1;memset(Matrix,0,sizeof(Matrix));int count=0;int row;int col;//axiswhile(1){std::cin>>row>>col;if(row==col&&row==-1){break;} Matrix[row][col]=1;//connect}//print();for(int i=1;i<=n2;i++){memset(Visited,0,sizeof(Visited));if(Hungarian(i)){count++;}/*for(int i=1;i<=m;i++){std::cout<<Match[i];}std::cout<<"\n";*/}if(count){std::cout<<count<<std::endl;//outputfor(int i=1;i<=m;i++){if(Match[i]!=0){std::cout<<i<<" "<<Match[i]<<std::endl;}}}else{std::cout<<"No Solution!"<<std::endl;}}return 0;
}

时间有些紧,可能码的代码有些纰漏,之后会更新
U3D项目也会定时更新的

二分图匹配 与 匈牙利算法(Hungary)相关推荐

  1. HDU 2063 过山车 (二分图匹配之匈牙利算法)

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

  2. 【小算法】二分图匹配之匈牙利算法详解(图例说明,代码亲测可用)

    在软件开发领域,任务指派和数据关联是一种常见业务需求,比如买卖订单的匹配,共享出行的人车匹配,及自动驾驶领域中目标追踪. 这都牵扯到一种技术,那就是数据关联,而匈牙利算法就是解决此类问题最典型的算法, ...

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

    匈牙利算法,很绕,其实写起来也就一点点长度.. bool find(int a){int i,j;for(i=head[a];i;i=next[i]){j=to[i];//获得相邻的点if(!unab ...

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

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

  5. 二分图匹配及匈牙利算法的全面讲解及python实现

    1.背景 在生活中常常遇到两组元素多对多匹配而又数目有限的情况,我们需要对其进行最大匹配数的分配,使效率最大化.例如,有一组压缩气缸和一组压缩活塞,每一个型号的压缩气缸有一个固定的内径大小,每一个型号 ...

  6. P3386 【模板】二分图匹配(匈牙利算法)

    展开 题目背景 二分图 感谢@一扶苏一 提供的hack数据 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入格式 第一行,n,m,e 第二至e+1行,每行两个正整数u ...

  7. 【2018ACM山东省赛 - B】Bullet(二分 + 二分图匹配,匈牙利算法,卡常)

    题干: Problem Description In GGO, a world dominated by gun and steel, players are fighting for the hon ...

  8. 【HDU - 1281 】棋盘游戏 (经典的二分图匹配,匈牙利算法,枚举删除顶点,必须边,关建边)

    题干: 小希和Gardon在玩一个游戏:对一个N*M的棋盘,在格子里放尽量多的一些国际象棋里面的"车",并且使得他们不能互相攻击,这当然很简单,但是Gardon限制了只有某些格子才 ...

  9. [ZJOI2007]矩阵游戏(二分图匹配、匈牙利算法)

    小Q是一个非常聪明的孩子,除了国际象棋,他还很喜欢玩一个电脑益智游戏--矩阵游戏.矩阵游戏在一个N *N黑白方阵进行(如同国际象棋一般,只是颜色是随意的). 每次可以对该矩阵进行两种操作: 行交换操作 ...

最新文章

  1. 使用JackJSON 流式API 创建JSON串【学习记录】
  2. mysql anyvalue报错_Mysql 的ANY_VALUE()函数和 ONLY_FULL_GROUP_BY 模式
  3. c#+ArcGIS Engine-获取矢量图层的空间参考
  4. EZ 2018 07 06 NOIP模拟赛
  5. 单点系统架构的可用性与性能优化
  6. python中int函数规则_python数字规则和内建函数
  7. Struts2-拦截器原理
  8. Linux系统编程---6(信号的机制,信号4要素,Linu常规信号表,定时器)
  9. python语言中包含的标准数据类型_Python对象——标准类型的分类
  10. 信息学奥赛一本通 1397:简单算术表达式求值 | OpenJudge NOI 1.12 01:简单算术表达式求值
  11. 基于linux的服务有哪些内容,linux基础(一)服务分类与管理
  12. JavaScript PHP 通过URLEncode字串判断其编码是UTF-8还是GBK
  13. 语音支持英语_语音识别英语_英语语音评分 - 云+社区 - 腾讯云
  14. 关于安装CNPM 与搭建VUE空白项目
  15. 机器学习笔记(二十五):支撑向量机(SVM)
  16. 无限联盟服务器,无限乱斗正式上线,全服服务器被网友挤爆!LOL重回巅峰状态!...
  17. 蒙特卡洛(随机试验)法计算π
  18. python常用库安装网址
  19. 论文阅读-基于遗传算法的NAS
  20. 【Unity3D游戏开发】GameObject.Find()、Transform.Find查找隐藏对象 (十)

热门文章

  1. 京东二面:高并发系统如何设计?
  2. Markdown学习,Windows常用快捷键,Dos命令,编译运行
  3. 联想x250为什么这么贵_联想ThinkPad x250评测:当之无愧的高端商务超极本
  4. 互联网科普知识【野狗】
  5. 云计算时代 自动化运维的开源云技术
  6. 跨专业插本计算机,专插本哪些可以跨专业
  7. 该邮件的附件格式不正确_正确挽回女友的方法:女友说不爱了该如何挽回?
  8. python控制excel选择区域,python针对excel的操作技巧
  9. 使用Loadrunner工具进行录制和回放的详细步骤及界面介绍
  10. 电脑监控怎样查看回放?