[hihoCoder] #1122 : 二分图二•二分图最大匹配之匈牙利算法
描述
上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了。因为过年时间并不是很长,所以姑姑希望能够尽可能在一天安排比较多的相亲。由于一个人同一天只能和一个人相亲,所以要从当前的相亲情况表里选择尽可能多的组合,且每个人不会出现两次。不知道有没有什么好办法,对于当前给定的相亲情况表,能够算出最多能同时安排多少组相亲呢?
同样的,我们先将给定的情况表转换成图G=(V,E)。在上一回中我们已经知道这个图可以被染成黑白两色。不妨将所有表示女性的节点记为点集A,表示男性的节点记为点集B。则有A∪B=V。由问题可知所有边e的两个端点分别属于AB两个集合。则可以表示成如下的图:

同样的,我们将所有的边分为两个集合。集合S和集合M,同样有S∪M=E。边集S表示在这一轮相亲会中将要进行的相亲,边集M表示在不在这一次进行。对于任意边(u,v) ∈ S,我们称u和v为一组匹配,它们之间相互匹配。在图G,我们将边集S用实线表示,边集M用虚线表示。得到下图:

则原问题转化为,最多能选择多少条边到集合S,使得S集合中任何两条边不相邻(即有共同的顶点)。显然的,|S|<=Min{|A|, |B|}。
那么能不能找到一个算法,使得能够很容易计算出尽可能多的边能够放入集合S?我们不妨来看一个例子:

对于已经匹配的点我们先不考虑,我们从未匹配的点来做。这里我们选择A集合中尚未匹配的点(A3和A4)考虑:
对于A3点,我们可以发现A3与B4右边相连,且都未匹配。则直接将(A3,B4)边加入集合S即可。

对于A4点,我们发现和A4相连的B3,B4点都已经匹配了。但是再观察可以发现,如果我们将A2和B2相连,则可以将B3点空出来。那么就可以同时将(A2,B2),(A4,B3)相连。将原来的一个匹配变成了两个匹配。
让我们来仔细看看这一步:我们将这次变换中相关联的边标记出来,如下图所示紫色的3条边(A2,B2),(A2,B3),(A4,B3)。

这三条边构成了一条路径,可以发现这条路径有个非常特殊的性质。虚线和实线相互交错,并且起点和终点都是尚未匹配的点,且属于两个不同的集合。我们称这样的路径为交错路径。
再进一步分析,对于任意一条交错路径,虚线的数量一定比实线的数量多1。我们将虚线和实线交换一下,就变成了下面的图:

在原来1个匹配的基础上,我们得到了2个新的匹配,S集合边的数量也增加了1。并且原来在已经匹配的点仍然是已经匹配的状态。
再回头看看A3点匹配时的情况:对于(A3,B4)这一条路径,同样满足了交错路径的性质。
至此我们得到了一个找新匹配的有效算法:
选取一个未匹配的点,查找是否存在一条以它为起点的交错路径。若存在,将该交错路径的边虚实交换。否则在当前的情况下,该点找不到可以匹配的点。
又有对于已经匹配的点,该算法并不会改变一个点的匹配状态。所以当我们对所有未匹配的点都计算过后,仍然没有交错路径,则不可能找到更多的匹配。此时S集合中的边数即为最大边数,我们称为最大匹配数。
那么我们再一次梳理整个算法:
1. 依次枚举每一个点i;
2. 若点i尚未匹配,则以此点为起点查询一次交错路径。
最后即可得到最大匹配数。
在这个基础上仍然有两个可以优化的地方:
1.对于点的枚举:当我们枚举了所有A中的点后,无需再枚举B中的点,就已经得到了最大匹配。
2.在查询交错路径的过程中,有可能出现Ai与Bj直接相连,其中Bj为已经匹配的点,且Bj之后找不到交错路径。之后又通过Ai查找到了一条交错路径{Ai,Bx,Ay,…,Az,Bj}延伸到Bj。由于之前已经计算过Bj没有交错路径,若此时再计算一次就有了额外的冗余。所以我们需要枚举每个Ai时记录B集合中的点是否已经查询过,起点不同时需要清空记录。
输入
第1行:2个正整数,N,M(N表示点数 2≤N≤1,000,M表示边数1≤M≤5,000)
第2..M+1行:每行两个整数u,v,表示一条无向边(u,v)
输出
第1行:1个整数,表示最大匹配数
- 样例输入
-
5 4
3 2
1 3
5 4
1 5 - 样例输出
-
2
伪代码:
Function FindPath(u)
For v∈u的相邻节点
标记v已经查询过
If v未匹配 or FindPath(v的匹配的点) Then
更改u的匹配为v
Return Ture
End If
End For
Return False For i ∈ V
清空标记
FindPath(i)
End If
二分图的性质
二分图中,点覆盖数是匹配数。
(1) 二分图的最大匹配数等于最小覆盖数,即求最少的点使得每条边都至少和其中的一个点相关联,很显然直接取最大匹配的一段节点即可。
(2) 二分图的独立数等于顶点数减去最大匹配数,很显然的把最大匹配两端的点都从顶点集中去掉这个时候剩余的点是独立集,这是|V|-2*|M|,同时必然可以从每条匹配边的两端取一个点加入独立集并且保持其独立集性质。
(3) DAG的最小路径覆盖,将每个点拆点后作最大匹配,结果为n-m,求具体路径的时候顺着匹配边走就可以,匹配边i→j',j→k',k→l'....构成一条有向路径。
(4)最大匹配数=左边匹配点+右边未匹配点。因为在最大匹配集中的任意一条边,如果他的左边没标记,右边被标记了,那么我们就可找到一条新的增广路,所以每一条边都至少被一个点覆盖。
(5)最小边覆盖=图中点的个数-最大匹配数=最大独立集。
代码!
#include <bits/stdc++.h>
using namespace std; int N, M;
vector<vector<int>> graph;
vector<int> link;
vector<bool> visited;
int a, b; int dfs(int u) {
for (auto v : graph[u]) if (!visited[v]) {
visited[v] = true;
if (link[v] == - || dfs(link[v])) {
link[v] = u;
return ;
}
}
return ;
} int hungary() {
int res = ;
for (int i = ; i <= N; ++i) {
visited.assign(N + , false);
res += dfs(i);
}
return res / ;
} int main() {
while (cin >> N >> M) {
graph.assign(N + , vector<int>());
link.assign(N + , -);
for (int i = ; i < M; ++i) {
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
int res = hungary();
cout << res << endl;
}
return ;
}
[hihoCoder] #1122 : 二分图二•二分图最大匹配之匈牙利算法的更多相关文章
- HihoCoder 1122二分图二 ---最大匹配之匈牙利算法
二分图二•二分图最大匹配之匈牙利算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了.因为过 ...
- hihoCoder #1127 : 二分图二·二分图最小点覆盖和最大独立集
#1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲 ...
- 【hihocoder 1122】二分图二•二分图最大匹配之匈牙利算法
[Link]:https://hihocoder.com/problemset/problem/1122 [Description] [Solution] 二分图匹配,匈牙利算法模板题; 这里我先把染 ...
- 二分图最大匹配:匈牙利算法的python实现
二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是 ...
- 51nod 2006 飞行员配对(二分图最大匹配) 裸匈牙利算法 求二分图最大匹配题
题目: 题目已经说了是最大二分匹配题, 查了一下最大二分匹配题有两种解法, 匈牙利算法和网络流. 看了一下觉得匈牙利算法更好理解, 然后我照着小红书模板打了一遍就过了. 匈牙利算法:先试着把没用过的左 ...
- "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)
博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利 ...
- 二分图最大匹配(匈牙利算法)简介& Example hdu 1150 Machine Schedule
二分图匹配(匈牙利算法) 1.一个二分图中的最大匹配数等于这个图中的最小点覆盖数 König定理是一个二分图中很重要的定理,它的意思是,一个二分图中的最大匹配数等于这个图中的最小点覆盖数.如果你还不知 ...
- 【模板】二分图最大匹配(匈牙利算法)/洛谷P3386
题目链接 https://www.luogu.com.cn/problem/P3386 题目大意 给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大 ...
- 无权二分图最大匹配 HDU2063 匈牙利算法 || Hopcroft-Karp
参考两篇比较好的博客 http://www.renfei.org/blog/bipartite-matching.html http://blog.csdn.net/thundermrbird/art ...
- HDU 2063 过山车 (最大匹配,匈牙利算法)
题意:中文题目 思路:匈牙利算法解决二分图最大匹配问题. #include <bits/stdc++.h> using namespace std; ; int mapp[N][N]; / ...
随机推荐
- zookeeperclient代码解读
近期一直在忙WebPageTest(下面简称wpt)开源库的改动工作,当中一项工作须要将zookeeper(下面简称zk)集成到wpt里. zk作为分布式系统的同步工具.实现了写的原子性(要么失败.要 ...
- VS2015不能修改安装路径问题
Python作为一门强大.开源的脚本语言也被ArcGIS所使用,但其开发编程环境(IDE)实现是太不方便了,VS2015终于集成了python开发,所以,也想对python多作一些了解和使用. 但今天 ...
- 使用web_url注意Resource的选项
在使用web_url的时候,一定注意Resource的使用,一般最好使用Resource=0,如果使用Resource=1,那么一定要修改配置. Resource Attribute If Resou ...
- 【原创】浅析密码学在互联网支付中的应用|RSA,Hash,AES,DES,3DES,SHA1,SHA256,MD5,SSL,Private Key,Public Key
一)概述 什么是互联网支付? 当支付遇到互联网,一场革命自然不可避免.成为现实的是传统的现金支付已经“退居二线”,各种在线支付方式成为人们日常消费的主要支付方式.银行推出的网银以及第三方支付公司推出的 ...
- jsp&html页面知识点集锦
CreateTime--2016年12月16日16:08:03Author:Marydonjsp&html页面知识点集锦1.标签的class属性 标签同时拥有多个class时,要写在同一个 ...
- Dubbo Monitor 配置
1. Dubbo Monitor 下载dubbo-monitor-simple-2.5.3-assembly.tar.gz 链接:http://pan.baidu.com/s/1gf88wDX 密码: ...
- iOS任何界面全屏炫酷倒计时,一句代码就够了
概述 iOS全屏炫酷倒计时,任何界面只需要调用一句代码就能实现,支持定制倒计时数字.倒计时结束时显示的文本.支持倒计时播放图片.开始倒计时和结束倒计时的block和delegate回调.支持定制文本颜 ...
- XMLHttpRequest cannot load ...谷歌浏览器跨域问题
HTML页面通过Ajax调用公网web服务时,浏览器请求发送成功,但是响应的 xhr.status==0,控制台报错如下 XMLHttpRequest cannot load http://ws.we ...
- 小白心目中的Java抽象类(abstract class)
在java开发中,我们有时会定义了一个父类,这个父类只有对方法的描述,但却没有在父类中写出对方法的实现,这种被定义的方法称为抽象方法.那么理所当然,含有抽象方法的类就称为抽象类.用关键字abstrac ...
- protobuf配置与使用
Protobuf配置与安装 1 安装与配置 1.protobuf是google公司提出的数据存储格式,详细介绍可以参考:https://code.google.com/p/protobuf/ 2.下载 ...