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

给定一个二分图,其中左半部包含n1n1个点(编号1~n1n1),右半部包含n2n2个点(编号1~n2n2),二分图共包含m条边。

数据保证任意一条边的两个端点都不可能在同一部分中。

请你求出二分图的最大匹配数。

二分图的匹配:给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,则称M是一个匹配。

二分图的最大匹配:所有匹配中包含边数最多的一组匹配被称为二分图的最大匹配,其边数即为最大匹配数。

输入格式

第一行包含三个整数 n1n1、 n2n2 和 mm。

接下来m行,每行包含两个整数u和v,表示左半部点集中的点u和右半部点集中的点v之间存在一条边。

输出格式

输出一个整数,表示二分图的最大匹配数。

数据范围

1n1,n25001≤n1,n2≤500,
1un11≤u≤n1,
1vn21≤v≤n2,
1m1051≤m≤105

输入样例:

2 2 4
1 1
1 2
2 1
2 2

输出样例:

2


#################################################################

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 100010, M = 1e5+10;
 5 int h[N], e[M], ne[M], idx;
 6 int match[N];
 7 bool f[N];
 8 int n1, n2, m;
 9 
10 void add(int a, int b){
11     e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
12 }
13 
14 bool find(int u){
15     for(int i = h[u];i != -1;i = ne[i]){
16         int j = e[i];
17         if(!f[j]){
18             f[j] = true;//标记已经预先匹配了
19             if(match[j] == 0 || find(match[j])){//找j的女朋友的男朋友还能不能和其他女的匹配
20                 match[j] = u;
21                 return true;
22             }
23         }
24     }
25     return false;
26 }
27 
28 int main(){
29     memset(h, -1, sizeof h);
30     cin >> n1 >> n2 >> m;   
31     while(m--){
32         int a, b;
33         cin >> a >> b;
34         add(a, b);
35     }
36     int res = 0;
37     //所有男同胞,n1那部分
38     for(int i = 1;i <= n1;++i){
39         memset(f, false, sizeof f);    
40         if(find(i)) ++res;
41     }
42     cout << res << endl;
43 }
View Code

猜你喜欢

转载自www.cnblogs.com/sxq-study/p/12238677.html
今日推荐