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

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

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

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

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

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

输入格式
第一行包含三个整数 n1n1、 n2n2 和 mm。

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

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

数据范围
1≤n1,n2≤500 1≤n1,n2≤500,
1≤u≤n1 1≤u≤n1,
1≤v≤n2 1≤v≤n2,
1≤m≤105 1≤m≤105
输入样例:

1
2
3
4
5
2 2 4
1 1
1 2
2 1
2 2

输出样例:

1
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<iostream>
#include<cstring>
using namespace std;
const int N=510;
int n1,n2,m;
int match[N],e[N][N];
bool st[N];

bool DFS(int b)//判断男生b能不能找到对象
{<!-- -->
    for (int i=1;i<=n2;i++)
    {<!-- -->
        if(e[b][i]==1&&st[i]==0){<!-- -->
            st[i]=1;
            if(match[i]==0||DFS(match[i])){<!-- -->||这个女生没对象或者这个女生的男朋友可以找到下一个
              match[i]=b;
              return true;
            }
        }
    }
        return false;
}
int main()
{<!-- -->       int sum=0,a,b;
        cin>>n1>>n2>>m;
        for (int i = 0; i < m; i++) {<!-- -->
            scanf("%d%d", &a, &b);
            e[a][b]=1;
        }
      for (int i = 1; i <=n1; i++) {<!-- -->
           memset(st,0,sizeof(st));
           if(DFS(i)){<!-- -->
               sum++;
           }
        }
        cout<<sum<<endl;
    return 0;
}