Files
python/TangDou/AcWing/P3386.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

67 lines
2.1 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 510;
const int M = 100010;
int n1, n2; //左边有n1个点右边有n2个点
int m; //共有m条边
int h[N], e[M], ne[M], idx; //邻接表
int match[N]; //右边点对应的左边哪个点
bool st[N]; //是不是已经匹配过
int res; //记录结果数值,成功匹配的对数
//邻接表建图
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
/**
* 功能:为每个男生找妹子
* @param x
* @return
*/
bool find(int u) {
//枚举每一个看上的集合
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (!st[j]) { //本轮次匹配时,没有男生相中的女生(动态,临时概念)
st[j] = true; //有人相中了
// match[j] == 0:如果j女生以前没有男朋友那OK可以
// find(match[j]):如果j的男朋友match[j]可以找其它女生
if (match[j] == 0 || find(match[j])) {
//设置女生j的男朋友是u,逆袭成功!
match[j] = u;
return true;
}
}
}
return false;
}
int main() {
//左边点数右边点数m条边
cin >> n1 >> n2 >> m;
//初始化邻接表
memset(h, -1, sizeof h);
//读入m条边建图
for (int i = 0; i < m; i++) {
int a, b;
cin >> a >> b;
//存的是左边指向右边,因为在代码中只找左边进行梳理,不会去遍历右边,所以只存一边
//不必保存右边结点指向左边结点的边
add(a, b);
}
//枚举左侧的每个点
for (int i = 1; i <= n1; i++) {
//表示后来的更牛,它看上的妹子,就会让其它人让出来,都是没有人选择过的状态!
//就是本轮状态标识的作用,而不是全局状态标识
memset(st, false, sizeof st);
//如果成功找到妹子个数加1
if (find(i)) res++;
}
//输出结果
printf("%d\n", res);
return 0;
}