模板:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int V=1100;
int n,m,k,x,y,pre[V];
//二分图中X集和Y集的节点数各为n、m,边数为k;匹配边集为pre,其中节点i所在的匹配边为(pre[i],i)
bool v[V],a[V][V];
//设二分图相邻矩阵为a,Y集合中节点的访问标志为v,若Y集合中的节点j已访问,则v[j]=true
bool dfs(int i){ //判断以X集合中的节点i为起点的增广路径是否存在
int j;
for(j=1;j<=m;j++){
if(!v[j]&&a[i][j]){ //搜索所有与i相邻的未访问点
v[j]=1; //访问节点j
if(pre[j]==0||dfs(pre[j])){
//若j的前驱是未盖点或者存在由j的前驱出发的增广路径,则设定(i,j)为匹配边,返回成功标志
pre[j]=i;
return 1;
}
}
}
return 0; //返回失败标志
}
int main(){
int i,ans;
scanf("%d%d%d",&n,&m,&k);
memset(a,0,sizeof(a));//二分图的相邻矩阵初始化
memset(pre,0,sizeof(pre));//匹配边集初始化为空
for(i=1;i<=k;i++){
scanf("%d%d",&x,&y);
a[x][y]=1;
}
ans=0; //匹配边数初始化为0
for(i=1;i<=n;i++){ //枚举X集的每个节点
memset(v,0,sizeof(v)); //设Y集合中的所有节点的未访问标志
if(dfs(i)) ans++; //若节点i被匹配边覆盖,则匹配边数+1
}
printf("%d\n",ans);
return 0;
}