博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

二分图最大匹配

大佬的详细解释:https://www.cnblogs.com/zzh666/p/9038299.html

这里我们来介绍一种求二分图最大匹配的算法——匈牙利算法

我们可以这样形象的描述匈牙利算法的原理:

我们相亲现场有五个男生和四个女生,假定一号男生喜欢(无特殊说明均视为两情相悦)一号和三号女生,二号喜欢一号,三号喜欢四号,四号喜欢三号和四号,五号喜欢三号。

那么我们模拟一下匈牙利的过程:

1、

2、

我们发现二号只能找一号,而一号还可以去找三号,所以我们让一去找三,而把一号女生给二号。

 3、

三去找四

4、

我们发现4号喜欢的女生都被选走了,怎么办?解决方法是令1单身而把3号女生给4号

5、

5号也喜欢3号,所以4号男生就凉了……

 

 总结:通过上面的例子我们发现匈牙利算法真的是瞎搞……这一秒你是人生赢家,下一秒可能就凉了。

于是我们用程序来模拟这个瞎搞的过程。

就是说如果你喜欢的女生没被选走或者选走她的人有其他选择那么她就是你的了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 using namespace std;
 6 int n,m,E,lin[100010],a[1000010],b[1000010],total,ans;
 7 int M[1010][1010];
 8 bool find(int now)
 9 {
10     for(int i=1;i<=m;i++)
11     {
12         if(!M[now][i]||b[i])continue;
13         b[i]=1;
14         if(!a[i]||find(a[i]))
15         {
16             a[i]=now;
17             return 1;
18         }
19     }
20     return 0;
21 }
22 int main()
23 {
24     scanf("%d%d%d",&n,&m,&E);
25     for(int i=1;i<=E;i++)
26     {
27         int u,v;
28         scanf("%d%d",&u,&v);
29         M[u][v]=1;
30     }
31     for(int i=1;i<=n;i++)
32     {
33         memset(b,0,sizeof(b));//记录是不是被找过 
34         if(find(i))ans++;
35     }
36     printf("%d",ans);
37 }
View Code

 

posted @ 2019-07-31 19:50  GUET_uzi  阅读(191)  评论(0编辑  收藏  举报

- 创建于 2018年9月1日

这是一位ACM爱好者&数学爱好者的个人站,内容主要是算法&数据结构&数学研究的技术文章,大部分来自学习,部分来源于网络,希望对大家有所帮助。