前言
这个算法网上讲解有很多,就不在细说,主要是给每个点找一条增广路,核心思路是在发现对面被配对后让之前的配对点腾个位置,腾位置成功的话此时找到一条增广路。要注意的地方是建边的方向和谁配对谁要联系起来,也就是说男生A到女生B连一条有向边后你就要用男生去找女生配对
实现
#include <bits/stdc++.h>
using namespace std;
#define maxnn 505
bool used[maxnn]; //表示第i个男生是否匹配过
int boyfriend[maxnn]; //表示第i个女生的男朋友编号 0表示没有
bool line[maxnn][maxnn]; //邻接矩阵
int k, m, n; //k条边 m个女生 n个男生
//含义:男生cur找到一个女朋友能否成功
bool dfs(int cur) {
for (int i = 1; i <= m; i++) {
if (line[cur][i] && !used[i]) { //有边并且这个女生在本次搜索树中没被考虑过
used[i] = true; //标记为本次考虑过的女生
if (!boyfriend[i] || dfs(boyfriend[i])) { //该女生没男朋友或者让其当前男朋友再成功找到女朋友
boyfriend[i] = cur; //这个女孩的男朋友换成当前的cur
return true;
}
}
}
return false;
}
int solve() {
int matchSize = 0;
for(int i = 1; i <= n; i++) {//给每个男孩配对一个女朋友 成功时s++
memset(used, false, sizeof(used)); //初始化 寻找下一个增广路
if (dfs(i))
matchSize++;
}
return matchSize; //最大匹配
}
int main() {
int u, v;
while (~scanf("%d", &k) && k) {
memset(line, false, sizeof(line)); //初试化每个人都没有边
memset(boyfriend, 0, sizeof(boyfriend)); //女生的男朋友没配对
scanf("%d%d", &m, &n);
for(int i = 1; i <= k; i++) {
scanf("%d%d", &u, &v);
line[v][u] = true; //注意这个建边容易出错 是女生中意男生 有向的!!! 我们要让男生去匹配女生要反向建边或者后面条件line要反过来
}
printf("%d\n", solve());
}
return 0;
}