「知识学习」二分图的最大匹配、完美匹配和匈牙利算法(HDU-2063)
定义
如果一个图\((E,V)\)的顶点集\(E\)能够被能够被分成两个不相交的集合\(X,Y\),且每一条边都恰连接\(X,Y\)中的各一个顶点,那么这个图就是一个二分图。
容易得知,它就是不含有奇数环的图(这个等价定义有时候很重要)。
一个匹配是一个边的集合,其中任意两条边都没有公共顶点。顾名思义可以得到一个图的最大匹配的定义。特别地,如果一个图的某个匹配中,所有顶点都是匹配点,那么它是一个完美匹配。
由完美匹配和最大匹配这两个定义我们可以得到两类问题:
- 有没有可能使得所有顶点都被匹配?
- 一个图中最多有多少个顶点参与了匹配?
求解最大匹配:匈牙利算法
对于一个正在求匹配的图,我们把依次经过非匹配边、匹配边、非匹配边、……形成的路径叫交替路;而如果一个未匹配点走交替路到了另外一个未匹配点,那么这条交替路成为增广路。
仔细思考一下,就会发现增广路的一个特点:非匹配边比匹配边多一条。这有什么意义呢?当我们把增广路中匹配边、非匹配边的性质交换后,匹配的性质不变,但是匹配边多了一条——我们改进了匹配。
因此,我们可以通过不停的找增广路来增加匹配中的匹配边和匹配点。然后,根据增广路定理,一个图找不到增广路时,就是它达到最大匹配的时候。
下面简单的说一下匈牙利算法:
- 从二分节点后的左边第1个顶点开始,挑选未匹配点进行搜索,寻找增广路。
a. 如果经过一个未匹配点,说明寻找成功。更新路径信息,匹配边数+1,停止搜索。
b. 如果一直没有找到增广路,则不再从这个点开始搜索。事实上,此时搜索后会形成一棵匈牙利树。我们可以永久性地把它从图中删去,而不影响结果。 - 由于找到增广路之后需要沿着路径更新匹配,所以我们需要一个结构来记录路径上的点。DFS 版本通过函数调用隐式地使用一个栈,而 BFS 版本使用
pre
数组。
上面提到了匈牙利树。那么这个是什么?匈牙利树他是这样的性质,从根节点到叶节点的路径均是交替路,且匈牙利树的叶节点都是匹配点。
例题:HDU-2063 过山车
经典板子题。
#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define ZERO(x) memset((x), 0, sizeof(x))
#define ALL(x) (x).begin(),(x).end()
#define rep(i, a, b) for (repType i = (a); i <= (b); ++i)
#define per(i, a, b) for (repType i = (a); i >= (b); --i)
#define QUICKIO \
ios::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
using namespace std;
typedef long long ll;
typedef int repType;
const int MAXN=505;
int k,m,n;
bool mat[MAXN][MAXN],used[MAXN];
int linker[MAXN];
int dfs(int boy)
{
rep(g,1,n) // girl
{
if(mat[boy][g] && !used[g])
{
used[g]=true;
if(linker[g]==-1 || dfs(linker[g]))
{
linker[g]=boy;
return true;
}
}
}
return false;
}
int hungary()
{
int ans=0;
memset(linker,-1,sizeof(linker));
rep(b,1,m) // boy
{
ZERO(used);
if(dfs(b)) ans++;
}
return ans;
}
int main()
{
while(cin>>k)
{
if(!k) break;
cin>>m>>n;
ZERO(mat);
rep(i,1,k)
{
int a,b; cin>>a>>b;
mat[a][b]=true;
}
cout<<hungary()<<endl;
}
return 0;
}
其他的题型
简单改一下:HYSBZ - 1191 超级英雄Hero
最小路径覆盖
二分图最大独立集
参考网址与资源
https://www.renfei.org/blog/bipartite-matching.html
https://www.cnblogs.com/YiXiaoZhou/p/5875040.html
https://www.cnblogs.com/kuangbin/archive/2012/08/26/2657446.html
「知识学习」二分图的最大匹配、完美匹配和匈牙利算法(HDU-2063)的更多相关文章
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577
题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...
- HDU_2255 二分图最佳完美匹配 KM匈牙利算法
一开始还没看懂这个算法,后来看了陶叔去年的PPT的实例演示才弄懂 用一个lx[]和ly[]来记录X和Y集合中点的权值,有个定理是 lx[i]+ly[j]==w[i][j](边权值) 则该点是最佳匹配, ...
- 【模板】二分图最大权完美匹配KM算法
hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...
- 【二分图最大权完美匹配】【KM算法】【转】
[文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...
- 紫书 例题11-10 UVa 1349 (二分图最小权完美匹配)
二分图网络流做法 (1)最大基数匹配.源点到每一个X节点连一条容量为1的弧, 每一个Y节点连一条容量为1的弧, 然后每条有向 边连一条弧, 容量为1, 然后跑一遍最大流即可, 最大流即是最大匹配对数 ...
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- UVA 1349 Optimal Bus Route Design (二分图最小权完美匹配)
恰好属于一个圈,那等价与每个点有唯一的前驱和后继,这让人想到了二分图, 把一个点拆开,点的前驱作为S集和点的后继作为T集,然后连边,跑二分图最小权完美匹配. 写的费用流..最大权完美匹配KM算法没看懂 ...
- HDU5090--Game with Pearls 二分图匹配 (匈牙利算法)
题意:给N个容器,每个容器里有一定数目的珍珠,现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放.最后将容器排序,如果可以做到第i个容器上面有i个珍珠,则Jerry胜出,反 ...
随机推荐
- luogu P1642 规划
嘟嘟嘟 看到最后让求一个比值,应该得往01规划上去想.令x = ∑v[i] / ∑c[i],则x * ∑c[i] = ∑v[i], ∑(v[i] - x * c[i]) = 0. 于是可以二分x(注意 ...
- shiro注解,初始化资源和权限,会话管理
有具体问题的可以参考之前的关于shiro的博文,关于shiro的博文均是一次工程的内容 注解: 新建一个类: 此时需要有admin的权限才可以执行下面的代码 public class ShiroS ...
- CQRS轻量级框架【CQRSlite】学习使用小记
前言 这几天在研究DDD和CQRS.快把我绕晕了.发现国外的好文质量还是挺高的.之所以先体验CQRSlite这个小框架,是因为看了一位大神写的文章:https://www.codeproject.co ...
- 十一、IntelliJ IDEA 中的版本控制介绍(上)
咱们已经了解了很多关于 IntelliJ IDEA 的使用方法,至少可以独立的运用 IntelliJ IDEA 进行项目开发啦!但是一个人进行项目开发更趋向于理想化,更多的则是团队协同开发.这时,咱们 ...
- 【nlogn LIS】 模板
总结:stl真好用 #include <cstdio> #include <cstring> #include <iostream> #include <al ...
- HDU 2018母牛的故事(类似斐波那契,找规律)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2018 母牛的故事 Time Limit: 2000/1000 MS (Java/Others) ...
- iOS应用启动原理图解 及ARC强弱引用
iOS应用启动原理图解(红色箭头表示strong强引用,绿色箭头代表weak若引用) 只要将UI控件拖到Storyboard里控制器的大view上,Xcode会自动将这些控件以强引用的形式加入到sel ...
- [MYSQL][2]索引
创建表时创建索引: 在已经存在的表上创建索引: 方法一 方法二 删除索引:
- 怎么将oracle的sql文件转换成mysql的sql文件
怎么将sql文件导入PowerDesigner中的方法(将oracle的sql文件转换成mysql的sql文件)呢? 怎么将xx.sql文件的数据库结构导入powerdesigner 的方法呢? 现讲 ...
- angularjs脏机制
Angular 每一个绑定到UI的数据,就会有一个 $watch 对象. watch = { name:'', //当前的watch 对象 观测的数据名 getNewValue:function($s ...