【图论】用匈牙利算法找女朋友(纯爱党的大胜利)
匈牙利算法
- 一、一些概念
- 1.二分图
- 2.二分图的匹配
- 二、匈牙利算法的实现步骤
- 1.情况一(你是我的唯一)
- 2.情况二(你们都是我的翅膀)
- 3.情况三(我会把你抢过来)
- 4.情况四(我爱的人已经有了爱人)
- 三、匈牙利算法的代码实现
一、一些概念
1.二分图
- 一定不含有奇数环,可能包含长度为偶数的环, 不一定是连通图
- 二分图是图论中的一种特殊模型。设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。准确地说:把一个图的顶点划分为两个不相交子集 ,使得每一条边都分别连接两个集合中的顶点。如果存在这样的划分,则此图为一个二分图,如下图所示的全都是二分图:
关于二分图有一个重要的定理:G为二分图的充要条件是G中的每一个环的长度都是偶数 在这里就不证明了。
2.二分图的匹配
- 二分图的匹配:给定一个二分图 G,在 G 的一个子图 M 中,M 的边集 {E} 中的任意两条边都不依附于同一个顶点,则称 M 是一个匹配。
- 二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。
理解起来是不是很抽象?没关系,我来举一个例子:让我们假设二分图的左边全为男生,右边全为女生,线连着的男女生为情侣关系,允许出现脚踏n条船等混乱的男女关系的情况,那么:
- 二分图的匹配:把二分图删除一些边使男女生之间的关系没有出现脚踏n条船的情况,就说删除边后得到的新图为一个匹配(允许出现单身狗的情况)
- 二分图的最大匹配:删除部分边使得保留的情侣数量最多,我们就称这个匹配为最大匹配。
比如在上面的4张图中,图1就是图3的一个最大匹配。
二、匈牙利算法的实现步骤
在故事的最开始,作为爱神丘比特的你得到了4对男女生之间的关系图
真是混乱的男女关系啊…
不过没关系,我们将化为纯爱战士,来让他们混乱的男女关系恢复正常!开始干活!
1.情况一(你是我的唯一)
首先我们看向男1,发现男1很纯情的只喜欢着女2,那么就成全他们吧。确定他们两个人的情侣关系。
2.情况二(你们都是我的翅膀)
接下来我们看向男2,发现男2喜欢着女1和女3两个女孩子。问问男2吧,他表示:我对这两个女孩子都是真心的,选谁都行!
选谁都行啊,那我们就随便选吧,把男2和女1牵上红线。
3.情况三(我会把你抢过来)
搞定,然后我们再看看男3,男3表示:我也喜欢女1啊!明明是我更加喜欢她!为什么?为什么她和别人在一起了啊!我不能接受!
嗯…看来我们的男3不想放弃啊,那我们尝试和男2交涉一下。
“男2呀,你有备胎吗?”
“有啊,怎么了?”
“男3看上了你女朋友,要不你和你备胎在一起,把你女朋友让给别人吧”
“嗯…好吧,记得让他请我吃饭”(作者对男2这种渣男表示强烈谴责!)
ok,这样的话事情就圆满解决了,可喜可贺可喜可贺。
4.情况四(我爱的人已经有了爱人)
解决了男2和男3的问题,我们再看向男4。
男4说:我喜欢女3!我想和女3在一起!
我看了看,女3不是男2的新女友吗?额…我再去找男2看看吧。
“什么?还要我换?大哥,我没别的备胎了,我拒绝!要是我还有备胎的话还差不多。”(作者对男2这种渣男表示强烈谴责!)
我们只好回头土脸的找到男4。那个,我们交涉失败了,女3是没戏了,要不你换一个追求对象我帮你争取一下?
男4低头沉思了一下,“我觉得吧,女4其实也挺可爱的。”
ok,安排!我们看了看,发现女4还是单身呢,那就成全你们吧。
最后,我们得到的最大匹配就是这样
男女关系正常了,纯爱党一脸满足~
- 总结:算法描述:
如果你想找的妹子已经有了男朋友,
你就去问问她男朋友,
你有没有备胎,
有备胎就把你女朋友让给我
你没有备胎我就只好找我的备胎
多么真实而实用的算法~
时间复杂度为O(nm),但是实际操作中时间一般会小于n*m。
多好的算法啊,连时间复杂度都这么优雅~
三、匈牙利算法的代码实现
例题链接:Acwing 二分图的最大匹配
匈牙利算法板子题,是必须要掌握的题目
给定一个二分图,其中左半部包含 n1 个点(编号 1∼n1),右半部包含 n2 个点(编号 1∼n2),二分图共包含 m 条边。数据保证任意一条边的两个端点都不可能在同一部分中。请你求出二分图的最大匹配数。二分图的匹配:给定一个二分图 G,在 G 的一个子图 M 中,M 的边集 {E} 中的任意两条边都不依附于同一个顶点,则称 M 是一个匹配。二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。输入格式
第一行包含三个整数 n1、 n2 和 m。接下来 m 行,每行包含两个整数 u 和 v,表示左半部点集中的点 u 和右半部点集中的点 v 之间存在一条边。输出格式
输出一个整数,表示二分图的最大匹配数。数据范围
1≤n1,n2≤500,
1≤u≤n1,
1≤v≤n2,
1≤m≤1e5
输入样例:
2 2 4
1 1
1 2
2 1
2 2
输出样例:
2
代码实现及分析
//#pragma GCC optimize(2)
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#include<ctime>
#include<cstring>
#include<list>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 7;
int n1, n2, m;
int h[550], ne[N], e[N], id = 1;// 链式前向星存图
bool st[N];//防止重边的情况导致死循环,防止一个男生重复询问一个女生导致死循环
int match[N];//用来存女生匹配的男生的编号void add(int a, int b)
{e[id] = b, ne[id] = h[a], h[a] = id++;
}int find(int x) //找男生x能不能匹配到女生
{for (int i = h[x]; i != -1; i = ne[i]) //遍历所有的边{int j = e[i];if (!st[j]) //防止重边导致的死循环{st[j] = true;if (!match[j] || find(match[j])) //如果这个女生还没有男朋友或者她现在的男朋友有备胎{match[j] = x; //那就让她男朋友换备胎,然后她成为x的女朋友return true; //匹配成功}}}return false; //匹配失败
}void solve()
{mem(h, -1);cin >> n1 >> n2 >> m;while (m--){int a, b;cin >> a >> b;add(a, b);}int res = 0;for (int i = 1; i <= n1; i++){mem(st, false); //重置if (find(i)) //给i找女朋友啦res++;}cout << res << endl;
}int main()
{std::ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);solve();return 0;
}
作者:Avalon Demerzel,喜欢我的博客就点个赞吧,更多图论与数据结构知识点请见作者专栏《图论与数据结构》
【图论】用匈牙利算法找女朋友(纯爱党的大胜利)相关推荐
- 图论 —— 二分图 —— 匈牙利算法
[基本概念] 1.交替路 从一个未匹配点出发,依次经过 非匹配边.匹配边.非匹配边- 形成的路径 2.增广路 定义:设 M 为二分图 G 已匹配边的集合,若 P 是图 G 中一条连通两个未匹配点的路径 ...
- python最长匹配_二分图最大匹配:匈牙利算法的python实现
二分图匹配是很常见的算法问题,一般用匈牙利算法解决二分图最大匹配问题,但是目前网上绝大多数都是C/C++实现版本,没有python版本,于是就用python实现了一下深度优先的匈牙利算法,本文使用的是 ...
- 二分图匹配及匈牙利算法的全面讲解及python实现
1.背景 在生活中常常遇到两组元素多对多匹配而又数目有限的情况,我们需要对其进行最大匹配数的分配,使效率最大化.例如,有一组压缩气缸和一组压缩活塞,每一个型号的压缩气缸有一个固定的内径大小,每一个型号 ...
- 图论 —— 二分图 —— KM 算法
[原理] KM 算法是用于求带权二分图的最优匹配的算法,其时间复杂度为 O(N^3). 1.首先选择顶点数较少的为 X 部(左点集),初始时对 X 部的每一个顶点设置顶标,顶标的值为该点关联的最大边的 ...
- c语言炉石传说算法设计,FZU Problem 2232 炉石传说(匈牙利算法)
Problem Description GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说.但是传统的炉石传说对于刚入门的GG学长来说有点复杂,所以他决定自己开发一个简化版的炉石传说. ...
- 匈牙利算法Hungarian algorithm
匈牙利算法是解决寻找二分图最大匹配的. 匈牙利算法(Hungarian Algorithm)是一种组合优化算法(combinatorial optimization algorithm),换句话说就是 ...
- 匈牙利算法——你一定可以看懂的图论算法
第一次讲解一个算法,也是最近才学到的一个算法,我的语言表达能力可能不是很强,排版也不是特别好,但是真的有认真在做一篇文章,如果有好的意见可以告诉我,非常感谢. 匈牙利算法是一种在多项式时间内求解任务分 ...
- [ACM_图论] The Perfect Stall 完美的牛栏(匈牙利算法、最大二分匹配)
描述 农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术.不幸的是,由于工程问题,每个牛栏都不一样.第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们 ...
- 常用代码模板3——搜索与图论(Bellman-Ford算法 、spfa 算法、floyd算法、Kruskal算法、染色法、匈牙利算法 )
目录 一.树与图的存储 二.树与图的遍历 (1) 深度优先遍历 -- 模板题 AcWing 846. 树的重心 (2) 宽度优先遍历 -- 模板题 AcWing 847. 图中点的层次 拓扑排序 -- ...
- 竟该找个我爱的人做我的女朋友或妻子呢?还是该找个爱我的人做我的女朋友或妻子呢?
石头问:我究竟该找个我爱的人做我的女朋友或妻子呢?还是该找个爱我的人做我的女朋友或妻子呢? 佛笑了笑:这个问题的答案其实就在你自己的心底.这此年来,能让你爱得死去活来,能让你感觉得到生活充实,能让你挺 ...
最新文章
- 瞄准VR游戏市场,这款数据手套还提供模块化定制
- 洛谷 P1003 铺地毯
- λ-矩阵(初等因子)
- jenkins 通过自动拉取Gitlab上的代码实现自动更新NGINX
- 如何使用 C# 中的 Tuple
- Linux基础——操作系统框架
- mysql image类型_MyCat教程【mysql主从复制实现】
- 【18】Python半成品购物车
- 不同表_一个公式搞定数据信息按类别拆分到不同工作表
- procedures
- 数商云SCM供应链协同管理系统解决方案
- 古代益智游戏汉诺塔java解决
- 淘宝能承受几百上亿的访问点击,而铁道部的网站为啥分分钟崩溃?
- vue中使用google地图(自定义label、信息窗口)
- [转]Linux: 结束查看进程命令
- matplotlib基础绘图命令之pie
- 传统防火墙与下一代防火墙的区别
- MFC入门基础(十二)控件 CScrollBar的使用
- 设计模式之禅(第2版)
- 聚焦 Android 11: Google Play 应用分发与盈利
热门文章
- CA证书服务器(6) 利用CA证书配置安全Web站点
- Swift2.0新特性
- 每天一个linux命令(25):chgrp命令
- 爱不意味这“sorry”
- 加载本地文件为String类型
- Error inflating class android.webkit.WebView Caused by: ...: String resource ID #0x2040003
- Springboot监控之二:Spring Boot Admin对Springboot服务进行监控
- linux 安装tuxedo
- React Native填坑之旅--Button篇
- centos mysql