二分图最大匹配 - 匈牙利算法
问题描述:
X集合(编号1~m),Y集合(编号m+1~n)。n,m<100. 给出若干组合(x, y)(相当于映射x->y),问最都能同时有几个组合(分配)。
分析:
题目可能简化描述得不太好,这显然是一个二分图最大匹配的问题。(二分图)
可以用匈牙利算法,或者网络流来求解。这里介绍匈牙利算法。
匈牙利算法的核心就是找增广路。不断找增广路,然后更新现有匹配M(M可以看成是X->Y的一个特殊的映射关系),每次更新,都能使匹配数增加一。当找不到增广路时,M就是最大的匹配。
算法具体流程:
①记X上点为u,Y上点为v。记f[v] 为u->v的映射对应的u,即v的对应点,f[v]=u。(初始清零)记vis[u]为本次寻找增广路,点u是否访问过。
dfs(u)表示当前从点u出发有没有增广路,若有返回1,否则为0.
②遍历X集合,(u=1~m),每次遍历vis[]清零,dfs(u),若有找到增广路(即dfs(u)=1),则匹配数加1。最后的匹配数即为最大。
③dfs中, 从u出发找v(邻接表存图),
I.若v本次未访问过(!!),即vis[v]=0。
1)若v为未盖点,即f[v]=0(尚无对应点),(说明增广路找到了,是以v为结尾的)。
2)若dfs(f[v])=1,即f[v]≠0,v是盖点,f[v]是v在当前匹配M中对应的u' (联系增广路的定义,虚实交错)。则dfs(u')=1,同样说明增广路找到。v在这条增广路中。
所以以上两个条件是并列的,或( || )关系。
于是对M和这条增广路进行取反。令f[v]=u,(更新了M),return 1;(找到,回溯).
3)没找到,遍历u的下一个邻接点v。
II.若vis!=0; 不处理。
其实这个算法我还是有些地方不是很明白。
代码:
#include<cstdio> #include<cstring> #include<vector> using namespace std; inline int Rint() {int x; scanf("%d", &x); return x;} #define MAXN 110 vector<int> G[MAXN]; int vis[MAXN]; int flag[MAXN]; //0-未盖 / 对应点-已盖 int n, m; int dfs(int u) { for(int i=0; i<(int)G[u].size(); i++) { int v = G[u][i]; if(!vis[v]) //未访问 { vis[v] = 1; if(!flag[v] || dfs(flag[v])) //!!不是dfs(v) -> dfs(flag[v]) 对应点 { flag[v] = u; return 1; } } } return 0; } int hungary() { memset(flag, 0, sizeof(flag)); int ans=0; // for(int i=1; i<=n; i++) //n??每个点 for(int i=1; i<=m; i++) //集合X中点 1~m { memset(vis, 0, sizeof(vis)); if(dfs(i)) ans++; } return ans; } void read_graph() { while(1) { int u = Rint(), v = Rint(); if(u == -1) break; G[u].push_back(v); //找的过程中,永远是从X集合出发的。u、flag[v]映射回u'... //G[v].push_back(u); } } void print_ans() //输出匹配M { for(int i=m+1; i<=n; i++) //flag[v]=u...v=m+1~n if(flag[i]) //v为盖点,输出对应的匹配边 { printf("%d->%d/n", flag[i], i); } } int main() { m = Rint(); n = Rint(); read_graph(); printf("%d/n", hungary()); print_ans(); }
转载于:https://www.cnblogs.com/tclh123/archive/2011/04/17/2587102.html
二分图最大匹配 - 匈牙利算法相关推荐
- 二分图最大匹配—匈牙利算法
二分图:又叫二部图,图G中顶点集V可以分成互不相交的子集(X,Y),并且图中的每一条边所关联的点分别属于两个不同的顶点集,则图G叫二分图.(不含奇环) 二分图的匹配:给定一个二分图G的子图M,M的边集 ...
- 二分图最大匹配-匈牙利算法
今天介绍 匈牙利算法 : 匈牙利算法,是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,由匈牙利数学家Edmonds于1965年提出,因而得名. 先介绍一下 ...
- 二分图最大匹配——匈牙利算法
二分图最大匹配 (一).二分图的介绍 1.定义 2.充要条件 (二).二分图的匹配 1.二分图的最大匹配 2.增广路径 3.匈牙利算法 (1).复杂度 (2).算法思路 (3).代码实现 (一).二分 ...
- 二分图最大匹配(匈牙利算法Dinic算法)
二分图最大匹配: 给出一个二分图,左边有若干个节点,右边有若干个节点,左边的节点想到匹配右边的节点,每个左边的节点每个都有若干个可以选择的对象,每个左边节点只能选择一个右边节点,每个右边节点也只能被选 ...
- 二分图最大匹配(匈牙利算法) POJ 3020 Antenna Placement
题目传送门 1 /* 2 题意:*的点占据后能顺带占据四个方向的一个*,问最少要占据多少个 3 匈牙利算法:按坐标奇偶性把*分为两个集合,那么除了匹配的其中一方是顺带占据外,其他都要占据 4 */ 5 ...
- NYOJ 题目239 月老的难题 (二分图最大匹配-匈牙利算法模板)
月老的难题 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一 ...
- NYOJ - 239 - 月老的难题 ( 二分图最大匹配 匈牙利算法 )
描述 月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘. 现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭. 现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸 ...
- 二分图最大匹配 -- 匈牙利算法
Algorithm.( Augmenting Path Algorithm ) Input: An X-Y bigraph G, a matching M in G, and the ...
- [HDOJ2819]Swap(二分图最大匹配, 匈牙利算法)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2819 题意:给一张n*n的01矩阵,可以任意交换其中的行或者列,问是否可以交换出来一个对角 ...
最新文章
- 《Groovy语言规范》-语法
- 【AutoML】强化学习如何用于自动模型设计(NAS)与优化?
- 计算机视觉与深度学习 | 深度学习与VO、SLAM、三维重建【论文及代码篇】
- Vmware拓展虚拟机硬盘容量
- C 标准库 —— time.h
- 苹果air3安兔兔html5是什么,iPad Air3什么时候上市?我们期待的苹果iPad Air3是什么样?(2)...
- 安卓手机老是自动保存图片_一张GIF图片就可以黑掉你的安卓手机?安装这款APP的你需要注意...
- js html table转json 反向生成数据源
- 铁打的春晚,流水的流量
- 微信小程序英语学习平台+后台管理系统
- 使用阿里字体彩色图标
- 怎么批量在文件名前面加上数字序号,对文件进行编号排序?
- java计算机毕业设计网上鲜花店系统源码+系统+数据库+lw文档
- 【论文阅读】DeepIM: Deep Iterative Matching for 6D Pose Estimation
- ubuntu下搭建pptp服务器
- HTML表单中get 和post 的区别
- Java使用华软通信能力平台实现短信发送
- win10装回win7
- 惠普服务器系统 unix,惠普:Unix服务器不可替代
- 从源码出发,会源码,懂源码
热门文章
- Linux用户相关的操作命令
- 理解 LruCache 机制
- Watson的未来就是IBM的未来
- 10月份出版图书《玩转虚拟机基于VMware+Windows》
- Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)...
- Linux 命令(54)—— trap 命令(builtin)
- modern php笔记---2.1、特性(命名空间、特性、性状)
- Django简介与基本命令
- Mongoose多数据库连接及实用样例
- 常见设计模式的思考1