匈牙利算法的超级简单的理解
前言
匈牙利算法用于解决二分图匹配问题,其重点不在于二分图而在于“匹配”。我第一次接触二分图匹配问题的时候尝试通过“不断找到最适合的配对”的方式来得到最大匹配数量,但是这么做会有超高的复杂度,会在两个集合中不断筛选最后得到“最适合的的配对”。但是学了匈牙利算法后我便知道这样子做的思路本身就算是不稳定的,因为这个“最适合”本身会就带有模糊属性,那么匈牙利算法怎么解决这个
二分图匹配的问题理解
我们把二分图的配对可以看作做一个男生群体和一个女生群体相亲,其中有些男女之间已经加了微信相互认识,而你要当这个媒婆,将一对认识的男女撮合结婚,问你最多可以撮合多少对男女?
匈牙利算法干了啥
不会吧!不会吧!不会吧!不会真有人在算法的世界里讲究道德吧?常见的思路就是撮合“当前最佳的一对,让后面剩余的选择尽可能多”,这样子做的话太麻烦啦!匈牙利算法选择了最原始直接的方法----抢老婆。我接下来会有一个极其不恰当的比喻完全是为了帮助大家理解题意别无他意,匈牙利算法让每一个男生自己轮流去找女朋友,只要是加了微信的都可以尝试去抢!如果当前男生A在咨询的这个女生是单身的,那么就直接在一起了,但是如果是名花有主的话,那么就看一下她的男朋友B的情况了,如果他的男朋友B可以用同样的方法抢到其他自己加了微信的女生当女朋友的话那么他会因为喜新厌旧而果断换新的,然后男生A就可以直接抢到这个女生了,又成功匹配一对。
C++代码参考
参考了这位大牛:https://blog.csdn.net/lemonxiaoxiao/article/details/108672039
#include <iostream>
#include <string.h>
using namespace std;
const int N = 510;
int v[N],p[N],con[N][N];
int b,g,m;
bool match(int x)
{
for(int i = 1;i <= g;i ++)
{
if(!v[i]&&con[x][i])
{
v[i] = 1;
if(!p[i] || match(p[i]))
{
p[i] = x;
return true;
}
}
}
return false;
}
int Hungarian()
{
int res = 0;
for(int i = 1;i <= b;i ++)
{
memset(v,0,sizeof v);
if(match(i)) res ++;
}
return res;
}
int main()
{
cin >> b >> g >> m;
while(m --)
{
int x,y;
cin >> x >> y;
con[x][y] = 1;
}
cout << Hungarian();
}