二分图匹配-匈牙利算法学习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图匹配-匈牙利算法学习相关的知识,希望对你有一定的参考价值。

首先二分图匹配的基础概念得清楚:
二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
匹配: 两两不含公共端点的边集合M称为匹配(简单的说就是右边的点只能连一条边)
极大匹配: 指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数
最大匹配: 所有极大匹配当中边数最大的一个匹配
增广路: 若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径.(百度百科)
简单理解就是 假如左边集合A点与右边集合P点 有一条已经匹配的边,而左边集合B点也与右边集合P点 有一条未匹配的边,能不能让A点去匹配右边集合的其他点。从而让B点俘获P点,达到匹配数量增大的情况。 个人理解。。如有错误,欢迎指正。

 

算法步骤:
1.将集合清空为0.
2.选择一个新的节点寻找增广路
3.重复2操作直到找不出增广路径为止
这里的Flash演示非常不错,简单易懂 https://comzyh.com/blog/archives/148/。

 

例题:
Usaco-4.2.2 The Perfect Stall
二分图匹配模板题目

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4  
 5 bool used[1005],cow[233][233];
 6 int fa[1005],tot;
 7 int n,m;
 8  
 9 bool find(int x){
10     for(int i=1;i<=m;i++){
11         if(!used[i] && cow[x][i]){
12             used[i]=true;
13             if(!fa[i] || find(fa[i])){
14                 fa[i]=x;
15                 return 1;
16             }
17         }
18     }
19     return 0;
20 }
21  
22 int main(){
23     scanf("%d%d",&n,&m);
24     for(int i=1;i<=n;i++){
25         int x;
26         scanf("%d",&x);
27         for(int j=1;j<=x;j++){
28             int a;
29             scanf("%d",&a);
30             cow[i][a]=1;
31         }
32     }
33     for(int i=1;i<=n;i++){
34         memset(used,0,sizeof(used));
35         if(find(i)) tot++;
36     }
37     printf("%d\n",tot);
38 }

 

以上是关于二分图匹配-匈牙利算法学习的主要内容,如果未能解决你的问题,请参考以下文章

二分图的最大匹配完美匹配和匈牙利算法

匈牙利算法

二分图匈牙利算法模板

二分图——匈牙利算法简述

匈牙利算法-二分图的最大匹配

二分图匹配--匈牙利算法