学习博客:https://www.cnblogs.com/fu3638/p/8784826.html

二分图匹配

基本概念:

给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

通常分为以下几种匹配:

一、 最大匹配

指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。这个问题通常使用匈牙利算法解决,朴素时间复杂度为O(V^3),使用邻接表的前提下时间复杂度为O(VE)。还有一种对匈牙利进行了优化的Hopcroft-Karp算法,时间复杂度为O(sqrt(V)*E)。

二、 完全匹配(完备匹配)

是在最大匹配下的一种特殊情况,指在二分图的两个集合中的点两两都能够得到匹配。

三、 最佳匹配

节点带有权值,在能够完全匹配的前提下,选择匹配方案使得权值之和最大。这个问题通常使用KM算法解决,时间复杂度O(V^3)。

算法介绍:

一、    匈牙利算法

1、基本概念:

1)交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边...形成的路径叫交替路。

2)增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。

如下图所示:

红边为三条已经匹配的边。从X部一个未匹配的顶点x4开始,能找到一条增广路:
x4->y3->x2->y1->x1->y2   所以到最后就是x1->y2   x2->y1  x3-y4  x4->y3

由增广路的定义可以推出下述三个结论:

①增广路的路径长度必定为奇数,第一条边和最后一条边都不属于M(已匹配子图),因为两个端点分属两个集合,且未匹配。

②增广路经过取反操作(已匹配边变为未匹配边,未匹配边变为已匹配边)可以得到一个更大的匹配M’。

③M为G的最大匹配当且仅当不存在相对于M的增广路径。

2、匈牙利算法能解决的问题:

1)最大匹配

最大匹配的匹配边的数目。

2)最小点覆盖数

二分图的最小点覆盖数=最大匹配数(König定理)

这里说明一下什么是最小点覆盖:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边。

3)最小路径覆盖

最小路径覆盖=顶点数-最大匹配数

在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,

且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点。

最小路径覆盖就是找出最小的路径条数,使之成为G的一个路径覆盖。

由上面可以得出:

①一个单独的顶点是一条路径;

②如果存在一路径p1,p2,......pk,其中p1 为起点,pk为终点,那么在覆盖图中,顶点p1,p2,......pk不再与其它的顶点之间存在有向边。

4)最大独立集

最大独立集=顶点数-最大匹配数。

独立集:图中任意两个顶点都不相连的顶点集合。

3、算法实现(别的博客找的)

我们以下图为例说明匈牙利匹配算法。

step1:从1开始,找到右侧的点4,发现点4没有被匹配,所以找到了1的匹配点为4 。得到如下图:

step2:接下来,从2开始,试图在右边找到一个它的匹配点。我们枚举5,发现5还没有被匹配,于是找到了2的匹配点,为5.得到如下图:

step3:接下来,我们找3的匹配点。我们枚举了5,发现5已经有了匹配点2。此时,我们试图找到2除了5以外的另一个匹配点,我们发现,我们可以找到7,于是2可以匹配7,所以5可以匹配给3,得到如下图:

此时,结束,我们得到最大匹配为3。

匈牙利算法的本质就是在不断寻找增广路,直到找不到位置则当前的匹配图就是最大匹配。

题目链接:https://www.51nod.com/Challenge/Problem.html#!#problemId=2006

看代码:

#include<iostream>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<map>
#include<queue>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn=1e2+5;
vector<int>v[maxn];
int link[maxn];//link[y]=x 即y和x匹配
bool vis[maxn];
int N,M;//用dfs寻找增广路
bool dfs(int u)
{for(int i=0;i<v[u].size();i++)//遍历所有与u能够匹配的飞行员
    {int t=v[u][i];if(!vis[t])//本次查找还没有走过这个点 走过就不需要在走了
        {vis[t]=true;if(link[t]==-1||dfs(link[t]))//如果t尚未被匹配  或者link[t] 能够找到其它能够替代的点 则把t点让给u
            {link[t]=u;return true;}}}return false;//找不到能与自己匹配的飞行员
}//返回最大匹配数
int max_match()
{memset(link,-1,sizeof(link));int ans=0;for(int i=1;i<=N;i++)//遍历二分图左边的所有点
    {memset(vis,false,sizeof(vis));//每次查找一个新的点都需要标记所有点没有走过 因为是一次新的查找if(dfs(i)) ans++;}return ans;
}
int main()
{cin>>N>>M;int a,b;while(cin>>a>>b){if(a==-1&&b==-1) break;v[a].push_back(b);//a和b可以匹配
    }int t=max_match();if(t==0) cout<<"No Solution!"<<endl;else cout<<t<<endl;return 0;
}

转载于:https://www.cnblogs.com/caijiaming/p/11163318.html

2006 飞行员配对(二分图最大匹配)相关推荐

  1. 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题

    题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...

  2. 51Nod-2006 飞行员配对(二分图最大匹配,匈牙利算法)

    2006 飞行员配对(二分图最大匹配) 题目来源: 网络流24题 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 第二次世界大战时期,英国皇家空军从沦陷国征募 ...

  3. 【网络流24题】【LOJ6000】搭配飞行员(二分图最大匹配,最大流Dinic)

    problem 给出一张二分图 求最大匹配 solution 新建一个源点s和汇点t 从源点s到集合A各连一条边,容量为1 从集合B到汇点t到各连一条边,容量为1 让二分图内部的边容量为1 很容易发现 ...

  4. 【网络流24题】解题报告:A、飞行员配对方案问题(最大流求二分图最大匹配)

    A.飞行员配对方案问题 (二分图最大匹配)(最大流)[提高+/省选- ] 题目链接 [问题分析] 二分图最大匹配问题. [建模方法] 在二分图的基础上增加源S和汇T. 1.S向X集合中每个顶点连一条容 ...

  5. 洛谷 P2756 飞行员配对方案问题 (二分图/网络流,最佳匹配方案)

    P2756 飞行员配对方案问题 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其 ...

  6. [codevs 1232] 飞行员配对方案问题

    [codevs 1232] 飞行员配对方案问题 题解: 做法一:二分图最大匹配. 做法二:用网络流求解二分图最大匹配... 但是都卡在输出路径上面...纠结要不要直接交数据,反正我有... 代码(未A ...

  7. P2756 飞行员配对方案问题【网络流24题】

    P2756 飞行员配对方案问题 文章目录 题目背景 题解: 代码: 题目背景 第二次世界大战期间,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相 ...

  8. 【洛谷 - P2756】飞行员配对方案问题(网络流最大流,输出方案)

    题干: 题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另 ...

  9. LuoguP2756 飞行员配对方案问题(最大流)

    题目背景 第二次世界大战时期.. 题目描述 英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2 名飞行员,其中1 名是英国飞行员,另1名是外 ...

最新文章

  1. 机器学习入门系列四(关键词:BP神经网络)
  2. android jni 调用java对象_Android NDK开发之Jni调用Java对象
  3. java小区管理的项目描述,基于jsp的小区信息管理-JavaEE实现小区信息管理 - java项目源码...
  4. 指针05:const修饰指针
  5. 计算机上机操作表格试题,全国计算机等级考试四Excel电子表格操作试题.doc
  6. 无线通信设备安装工程概预算编制_如何编制膜结构工程安装方案?
  7. mac时钟屏保_【win/mac】抖音网红八卦时钟屏保动态壁纸,快来体验
  8. QQ信任登陆注册开发者帐号
  9. C++C++ 编写GoFGoF设计模式里Lexi样例
  10. Warning [gazebo.cc:215] Waited 1seconds for namespaces.
  11. el-table单元格中加上横向柱状图
  12. 联通数据采集交换平台BDE的配置
  13. 【DB宝14】在Docker中只需2步即可拥有Oracle 11g企业版环境(11.2.0.4)
  14. 敏捷开发-故事与估算
  15. valist:解决变参问题
  16. MATLAB绘制圆、椭圆、矩形等基本平面图形
  17. 射频微电子学自存笔记
  18. 当企业面临困境时,你该怎么办?——听谢欣老师谈他眼中的酷讯
  19. elastic-job分片规则
  20. 如何设置WORD中图片自动编号

热门文章

  1. PC服务器实现海量数据存取的方法
  2. # ; @REM !等符号在WINCE6.0下的意义和作用
  3. 关于通过webclient和JSON格式报文与服务器之间通讯的解决方法和遇到的难题
  4. ACL 2021 | PENS: 个性化新闻标题生成数据集
  5. 速成pytorch学习——6天Dataset和DataLoader
  6. 计算机视觉目标检测算法总结2——基于深度学习
  7. ACL2022奇葩标题大赏
  8. Airbnb搜索:深度学习排序算法如何进化?
  9. png 微软ppt 透明度_花了8+小时,做了4页禅宗PPT定制!
  10. 同步带轮介绍_Synchroflex丨红色GENIII同步带丨Mulco