匈牙利算法
基础例题:【模板】二分图最大匹配
题目描述
给定一个二分图,其左部点的个数为 n,右部点的个数为 m,边数为 e,求其最大匹配的边数。
左部点从 1 至 n 编号,右部点从 1 至 m 编号。
不多bb,直接上代码
算法主要步骤:
- 从第一位开始找(先到先得)
- 后来者如果想匹配的对象已经被别人匹配走了,如那位先匹配者有其它匹配选择,就让给后来者,没有就让他爬
- 如果后来者真的啥也匹配不到了,那就爬
整个过程可用递归实现
总代码
#include<bits/stdc++.h>
using namespace std;
int n,m,e,match[501],ans;//match用来记录与被匹配者匹配的人是否还有其它选择
vector<int> bian[50010];//记录可选匹配对象
bool vis[501];//记录匹配对象是否已经被匹配
bool dfs(int u){
for(int i=0;i<bian[u].size();i++){
int v=bian[u][i];
if(vis[v])continue;//倘若之前已经找过她了,那放弃吧
vis[v]=1;
if(match[v]==0||dfs(match[v])){//倘若没被匹配过,或者其匹配者有其它选择,那就让他匹配其它选择,新来的匹配旧选择
match[v]=u;
return 1;//匹配到了
}
}
return 0;
}
int main(){
cin>>n>>m>>e;
for(int i=1;i<=e;i++){
int u,v;
cin>>u>>v;
bian[u].push_back(v);//记录匹配选择
}
for(int i=1;i<=n;i++){
memset(vis,0,sizeof(vis));//记得清空vis
if(dfs(i))ans++;//匹配到了就ans++
}
cout<<ans;
return 0;
}
其实,说来说去,就是一个绿与被绿,选择备胎的过程(6666666)