P3386 【模板】二分图最大匹配
P3386 【模板】二分图最大匹配
大意
给你 \(e\) 条二分图连边的关系,你需要找到最大的匹配方案。
思路
使用匈牙利算法。
本质上是不断的求增广路径,我们在开始的啥时候就正常的选,如果选到一个,发现其所连向的点已经被选过了,这时候,我们不妨从这个点出发,反向的找一条增广路径,如果可以找出一条更长的增广路径,那么我们就把这条重新记录一下。
我们可以证明,右边的每一个点只会被增广一次,因为我们可以反证一下,若右边的点被增广了两次,则第一次就应该找到那个最优的,而不会在第二次去更新,故矛盾,假设不成立。
代码
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int MAXN = 505;
int n, m, e;
int mac[MAXN];
vector<int> g[MAXN];
bool vis[MAXN];
bool dfs(int u){
for(int i = 0;i < g[u].size();i ++){
int v = g[u][i];
if(!vis[v]){
vis[v] = true;
if(mac[v] == -1 || dfs(mac[v])){
mac[v] = u;
return true;
}
}
}
return false;
}
int hungary(int n){
int cnt = 0;
memset(mac, -1, sizeof(mac));
for(int i = 1;i <= n;i ++){
memset(vis, 0, sizeof(vis));
cnt += dfs(i);
}
return cnt;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> m >> e;
for(int i = 1;i <= e;i ++){
int u, v; cin >> u >> v;
g[u].push_back(v);
}
cout << hungary(n) << '\n';
return 0;
}
本文来自一名高中生,作者:To_Carpe_Diem

浙公网安备 33010602011771号