P3386 【模板】二分图最大匹配
题目描述
给定一个二分图,其左部点的个数为 nnn,右部点的个数为 mmm,边数为 eee,求其最大匹配的边数。
左部点从 111 至 nnn 编号,右部点从 111 至 mmm 编号。
输入格式
输入的第一行是三个整数,分别代表 nnn,mmm 和 eee。
接下来 eee 行,每行两个整数 u,vu, vu,v,表示存在一条连接左部点 uuu 和右部点 vvv 的边。
输出格式
输出一行一个整数,代表二分图最大匹配的边数。
输入输出样例 #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≤5001 \leq n, m \leq 5001≤n,m≤500。
- 1≤e≤5×1041 \leq e \leq 5 \times 10^41≤e≤5×104。
- 1≤u≤n1 \leq u \leq n1≤u≤n,1≤v≤m1 \leq v \leq m1≤v≤m。
不保证给出的图没有重边。
C++实现
#include <bits/stdc++.h>
using namespace std;
int n, m, e, ans;
int tim[505]; //时间戳防重边
int rec[505]; //记录谁与谁配对
vector < int > edge[505]; //存边
bool dfs(int x, int t) { //当前节点, 时间戳
if (tim[x] == t) return false; //当前轮次已访问直接返回
tim[x] = t; //标记
for (auto y : edge[x])
if (rec[y] == 0 || dfs(rec[y], t)) {
rec[y] = x; //匹配
return true;
}
return false;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m >> e;
for (int i = 1; i <= e; i++) {
int x, y;
cin >> x >> y;
edge[x].push_back(y);
}
for (int i = 1; i <= n; i++)
if (dfs(i, i)) ans++;
cout << ans << endl;
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
用C++实现信奥题 P3386 【模板】二分图最大匹配&spm=1001.2101.3001.5002&articleId=157169585&d=1&t=3&u=516b2cc40807462a957491810551babb)
2740

被折叠的 条评论
为什么被折叠?



