标准二分图匹配----匈牙利算法
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。
————度娘
看不懂没关系(我也看不懂qwq),下面我就讲一下二分图匹配的简单理解方式:
首先说明一下题:匈牙利村中有有n个壮汉(下边简称gay)有m个美女(下面简称bitch)有k对关系(有关系说明2人可以结婚)求最多有多少对夫妻。
提醒一句 不支持同性结婚,
输入:第一行 n m k
第二行到k+1行 a b(表示gay a和bitch b有关系)
输出
最多夫妻个数(即最大匹配个数)
很明显这是个裸的网络流
样例输入
4 4 6
1 1
1 2
1 4
2 1
2 3
3 2
4 4
样例输出
3

讲下样例,顺便说下思路:
gay 1和bitch 1 2 4 有关系,为了保证最大匹配我们先让 gay 1和bitch 1连;
接着看gay 2,gay 2和bitch 1 3有关系,为了保证最大匹配我们让 gay 2和bitch 1连,
但这时gay 1已经和bitch 1连了,我们怎么做呢,
明显gay 1和bitch 2 4也有关系,gay 1想:忍了忍了,
于是开开心心(不乐意)地和bitch 2搞上了;
再看 gay 3只和bitch 2有关系,
但这时gay 1已经和bitch 2连了,我们怎么做呢,
明显gay 1和bitch 4也有关系,gay 1想:算了算了,
于是开开心心(不乐意)地和bitch 4搞上了;
再看 gay 4只和bitch 4有关系,
但 gay 1已经和bitch 4搞上了,而且gay 1的其他伪老婆也跑了,gay 1心想:mmp,干他娘的;
然后gay 4就吓跑了,发现没其他的bitch 和他有关系,于是孤独一生。
说完大体思路后,我们讲讲代码实现。我们可以用一个(bool) map【】【】储存二者之间的关系,每次遍历一遍判断该gay(或bitch)是否与另一个bitch(或gay)有关系,每次用个vis【】来判断是否能连,不能连就连下一个直到无点可连。这就是中心内容了。。。上代码吧。。。
#include<cstdio> #include<cstring> using namespace std; int map[1006][1006]; bool vis[1005]; int link[1005]; int n,m,k,ans=0; bool dfs(int a) { for(int i=1;i<=n;i++) { if(map[a][i]==1&&!vis[i]) { vis[i]=1; if(dfs(link[i])||link[i]==0) { link[i]=a; return true; } } } return false; } int main() { scanf("%d%d%d",&n,&m,&k); //n男的m女的k关系数 int a,b; while(k--) { scanf("%d%d",&a,&b); map[a][b]=1; //关联关系 } for(int i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); //刷新一遍 if(dfs(i)==true) //判断能否不改变其他的点的匹配数的前提下使当前点得到匹配 ans++; } printf("%d\n",ans); return 0; }
第一次讲课,可能讲不好,望大家包涵qwq....
欢迎指正,欢迎提问。
转载请注明——sxld-lgl

浙公网安备 33010602011771号