题目描述
给定一个二分图,其左部点的个数为 n n n,右部点的个数为 m m m,边数为 e e e,求其最大匹配的边数。
左部点从 1 1 1 至 n n n 编号,右部点从 1 1 1 至 m m m 编号。
输入格式
输入的第一行是三个整数,分别代表 n n n, m m m 和 e e e。
接下来 e e e 行,每行两个整数 u , v u, v u,v,表示存在一条连接左部点 u u u 和右部点 v v v 的边。
输出格式
输出一行一个整数,代表二分图最大匹配的边数。
样例 #1
样例输入 #1
1 1 1
1 1
样例输出 #1
1
样例 #2
样例输入 #2
4 2 7
3 1
1 2
3 2
1 1
4 2
4 1
1 1
样例输出 #2
2
提示
数据规模与约定
对于全部的测试点,保证:
- 1 ≤ n , m ≤ 500 1 \leq n, m \leq 500 1≤n,m≤500。
- 1 ≤ e ≤ 5 × 1 0 4 1 \leq e \leq 5 \times 10^4 1≤e≤5×104。
- 1 ≤ u ≤ n 1 \leq u \leq n 1≤u≤n, 1 ≤ v ≤ m 1 \leq v \leq m 1≤v≤m。
不保证给出的图没有重边。
代码:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N=1e6+10;
int st[N],match[N];
int g[1005][1005];
int n,m,k;
bool find(int u)
{
for(int i=1;i<=m;i++)
{
if(st[i])
{
continue;
}
if(g[u][i])
{
st[i]=true;
if(match[i] == -1 || find(match[i]))
{
match[i]=u;
return true;
}
}
}
return false;
}
int main()
{
memset(match,-1,sizeof match);
cin>>n>>m>>k;
for(int i=0;i<k;i++)
{
int x,y;
cin>>x>>y;
g[x][y]=1;
}
int res=0;
for(int i=1;i<=n;i++)
{
memset(st,false,sizeof st);
if(find(i))
{
res++;
}
}
cout<<res;
}