二分最大匹配(匈牙利算法+HK算法)
http://acm.hdu.edu.cn/showproblem.php?pid=2063
匈牙利算法:http://blog.csdn.net/dark_scope/article/details/8880547
Hopcroft-Karp算法:http://blog.csdn.net/xu3737284/article/details/8973720
问题概述: 一场聚会上有n个男生m个女生,每个男生都可能对多名女生有好感,如果有一对男女有好感,他们就可
以被撮合在一起,否则不能,请问在这个聚会中最多能有多少对男女撮合在一起?(二分图最大匹配)
输入样例: 对应输出:
6 3 3 3
1 1
1 2
1 3
2 1
2 3
3 1
最小点覆盖数:假如选了一个点就相当于覆盖了以它为端点的所有边,你需要选择最少的点来覆盖所有的边
独立集:图中任意两个顶点都不相连的顶点集合
交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路
→定理1:二分图最大匹配==最小点覆盖数
→定理2:顶点数-二分图最大匹配==最大独立集
→定理3:最大匹配是增广路不存在的充要条件
匈牙利算法:
解决问题:二分图最大匹配,本质DFS,复杂度V*E
#include<stdio.h>
#include<string.h>
int k, n, m, road[505][505], vis[505], link[505];
int Sech(int x);
int main(void)
{int i, a, b, ans;while(scanf("%d", &k), k!=0){ans = 0;scanf("%d%d", &n, &m);memset(road, 0, sizeof(road));memset(link, 0, sizeof(link));for(i=1;i<=k;i++){scanf("%d%d", &a, &b); /*road[a][b]==1表示第a个男生对第b个女生有好感,否则没有*/road[a][b] = 1;}for(i=1;i<=n;i++) /*算法思路:从第一个男生开始,尽可能让每个男生匹配成功,或是还有心仪的女生名花无主直接匹配,或是调整前面已有的匹配已达到找到自己心仪的女生*/{memset(vis, 0, sizeof(vis)); /*vis为标记数组,vis[k]==1表示第k个女生已经被查找过并试图改变过该妹子的归属问题,没有必要再次查找*/if(Sech(i)==1) /*第i个男生匹配成功*/ans++;}printf("%d\n", ans);}return 0;
}int Sech(int x)
{int i;for(i=1;i<=m;i++) /*对于每个男生,先枚举每一个女生*/{if(vis[i]==0 && road[x][i]==1) /*如果这个女生还未被查找且这个男生对这个女生有好感*/{vis[i] = 1; /*标记*/if(link[i]==0 || Sech(link[i])==1) /*如果这个女生名花无主或是可以腾出个位置*/{ /*这其实是一个寻找增广路的过程*/link[i] = x; /*恭喜这一对男女配对成功*/return 1;}}}return 0;
}
Hopcroft-Karp算法:
主要思想:在每次增广的时候同时寻找几条不相交的最短增广路,形成极大增广路集,随后可以沿着这几条增广路
同时进行增广
解决问题:二分图最大匹配,本质BFS,复杂度sqrt(V)*E
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int n, m, dis, val[1005][1005], lx[1005], ly[1005], dx[1005], dy[1005], vis[1005];
int HKSech(); /*lx、ly表示左集合右集合的点连接情况*/
int Sech(int u);
int main(void)
{int k, u, v, i, ans;while(scanf("%d", &k), k!=0){scanf("%d%d", &n, &m);memset(val, 0, sizeof(val));while(k--){scanf("%d%d", &u, &v);val[u][v] = 1;}ans = 0;memset(lx, -1, sizeof(lx));memset(ly, -1, sizeof(ly));while(HKSech()){memset(vis, 0, sizeof(vis));for(i=1;i<=n;i++){if(lx[i]==-1 && Sech(i)) /*如果i点还没有连接(可能是增广路的起始),则尝试进行连接*/ans++;}}printf("%d\n", ans);}return 0;
}int HKSech()
{int i, x;dis = 100000000;queue<int> q;memset(dx, -1, sizeof(dx)); /*dx、dy用来标记当前点是否在一个交替路中*/memset(dy, -1, sizeof(dy));for(i=1;i<=n;i++){if(lx[i]==-1) /*初始化左集合中没有连接的点入队*/{q.push(i);dx[i] = 0;}}while(q.empty()==0) /*广搜寻找目前最短的增广路集合*/{ /*在寻找增广路集的每一个阶段所寻找到的最短增广路都具有相等的长度,并且随着算法的进行最短增广路的长度是越来越长,最多只需要增广ceil(sqrt(n))次就可以得到最大匹配*/x = q.front();q.pop();if(dx[x]>dis) /*已经找到,结束*/break;for(i=1;i<=m;i++){ /*以下x∈左集合,i∈右集合*/if(val[x][i] && dy[i]==-1) /*如果x与i有边且i点还未被搜到*/{dy[i] = dx[x]+1; /*i点在一条交替路中,标记*/if(ly[i]==-1) /*如果i点没有和任何一点连接,这条交替路为增广路!*/dis = dy[i];else{dx[ly[i]] = dy[i]+1;q.push(ly[i]);}}}}if(dis==100000000) /*如果找不到增广路,说明已经满足最大匹配*/return 0;return 1;
}int Sech(int x)
{int i;for(i=1;i<=m;i++){if(val[x][i] && vis[i]==0 && dy[i]==dx[x]+1) /*如果i在一条交替路中*/{vis[i] = 1;if(ly[i]!=-1 && dy[i]==dis) /*如果i点已经被连接但是当前交替路的长度==找到的增广路的长度,说明这条路不是当前最短增广路*/continue;if(ly[i]==-1 || Sech(ly[i])) /*如果i点未连接,或者可以腾出个位置*/{ly[i] = x;lx[x] = i;return 1;}}}return 0;
}
二分最大匹配(匈牙利算法+HK算法)相关推荐
- 二分图的最大匹配—匈牙利算法
[基本概念]: 二分图: 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分 ...
- 二分图的最大匹配 匈牙利算法
基本概念 1.二分图: 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别 ...
- 二分图最大匹配—匈牙利算法
二分图:又叫二部图,图G中顶点集V可以分成互不相交的子集(X,Y),并且图中的每一条边所关联的点分别属于两个不同的顶点集,则图G叫二分图.(不含奇环) 二分图的匹配:给定一个二分图G的子图M,M的边集 ...
- HDU 2389(二分最大匹配优化算法,Hopcroft-Carp)
HDU 2389(二分最大匹配优化算法,Hopcroft-Carp) 题目链接: 大致题意; 您能帮助客人在下雨之前尽可能多地找到一把雨伞? 给定所有客人的位置和跑步速度,雨伞位置,到下雨开始时的时间 ...
- 二分图最大匹配-匈牙利算法
今天介绍 匈牙利算法 : 匈牙利算法,是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,由匈牙利数学家Edmonds于1965年提出,因而得名. 先介绍一下 ...
- hdu2389-二分匹配HK算法
题意:就是将在t秒后下雨然后给你n个人的坐标和速度m把伞的坐标然后求最多可以有几个人拿到伞 题解思路:求出哪个人可以和哪把伞匹配后就是二分最大匹配但是用匈牙利算法肯定会超时那么此时就要用HK算法优化一 ...
- 二分图匹配 Hopcroft-Carp (HK) 算法详解 附例题
了解这个算法之前 首先了解一个概念 :增广路 增广路 :简单的说 ,是二分图匹配中的一条边,他总是从 左边集合的一个点出发通过一条没有被匹配的边连接到右边集合,再从该点通过一条 匹配过的边连接到右边集 ...
- 二分图HK算法[数论+二分图最大独立集]:Lightoj1356
Prime Independence LightOJ - 1356 题目大意:给你n个数,你从这个集合中挑选出若干个数,使得这个集合的数里面两两之间a/b!=k[k是质数并且a>b]a/b!=k ...
- 二分图(H-K算法)
Problem Description You're giving a party in the garden of your villa by the sea. The party is a hug ...
最新文章
- CCF NOI1150 确定进制
- 【CyberSecurityLearning 附】批处理命令拓展(netsh/netstat/net)
- java 排序stackoverflow_JAVA开发知识点
- 直播报名 | 小身材大能量!用英伟达智能小车Jetbot玩转深度学习
- 追踪源码自定义负载均衡策略
- 实现一个基于动态代理的 AOP
- 关于对象不能直接访问私有成员的误区(转)
- 理解JavaScript原型
- 透过 AI 技术解读人的行为 研究开发回声定位
- 学成在线-第16天-讲义- Spring Security Oauth2 JWT RSA加解密
- Fleck WebSocket使用
- 初入职常见问题:弱网络环境构造、压力测试、内存泄漏、性能持续优化工具
- 线性代数学习笔记——第五十二讲——齐次方程组解的性质和基础解系
- android蓝牙传输文件到mysql_蓝牙opp文件发送过程剖析
- This connection has been closed,应用连接数据库后1-3小时,即自动断开连接
- hive正则表达式regexp_extract
- python环境变量配置
- HTML5期末大作业:电影网页设计——在线影院6页(代码质量好) 学生DW网页设计作业源码 web课程设计网页规划与设计
- c语言程序设计第三版杜有福,C语言程序设计习题答案 杜有福
- 蚁族程序员自述:冬天盼暖气,面朝西二旗
热门文章
- python画图代码大全-Python实现画图软件功能方法详解
- 语音识别合成助手-语音识别合成助手下载 v20190223免费版--pc6下载站
- vue-drag-resize + html2canvas合成图片并下载
- 小学学校计算机室文化建设方案,计算机室文化建设方案
- 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)
- 在FFMPEG中使用libRTMP的经验
- completable java_java8 CompletableFuture异步编程
- CyclicBarrier(栅栏)实现高并发测试
- MyBatis动态SQL的List传值错误
- 【luogu3834】【模板】可持久化线段树 2(主席树),静态区间第K小值