/****************************************************二分图匹配(匈牙利算法的DFS实现)INIT:g[][]两边定点划分的情况CALL:res=hungary();输出最大匹配数优点:适于稠密图,DFS找增广路快,实现简洁易于理解时间复杂度:O(VE);适用范围:二分图的 最小顶点覆盖 ==== 最大匹配DAG图的 最小路径覆盖数 == 节点数 – 最大匹配数二分图的 最大独立集数 = 节点数 – 最大匹配数****************************************************/#include <string>#include <stdio.h>using namespace std;#define MAXN 1000int path[MAXN][MAXN];bool sign[MAXN]; //v是否已经匹配的标志int road[MAXN]; //匹配存在road中,从v->u的int u_num, v_num; //两个集合各自的元素总数bool dfs(int u){ for(int v=0; v<=v_num; v++) //这里加个等于号和题目有关 { if(path[u][v] && !sign[v]) //path[u][v] 存在关联与否,与没有匹配的v结合 { sign[v] = true; //结合后的v设定为匹配 if(road[v] == -1 || dfs(road[v]) ) { road[v] = u; //保存u->v的匹配路径 return true; } } } return false;}int hungray(){ int match = 0; //匹配数 memset(road, -1, sizeof(road) ); //匹配路径初始化 for(int u=0; u<=u_num; u++) { memset(sign, 0, sizeof(sign) ); //每查找一次u, v集合相应清空 if(dfs(u) ) match++; } return match;}void input(int n){ memset(path, 0,sizeof(path) ); for(int i=0; i<n; i++) { int u, v; scanf("%d%d", &u, &v); path[u][v] = 1; }}int main(){ int n; while(scanf("%d")!=EOF) { scanf("%d%d", &u_num, &v_num); input(n); printf("%d\nn", hungray() ); } return 0;}