二分图学习指南
前置芝士
匈牙利算法
时间复杂度:O(n*m)
二分图的最大匹配
[problem description]
给定一个二分图,其左部点的个数为 n,右部点的个数为 m,边数为 e,求其最大匹配的边数。
左部点从 1至 n 编号,右部点从 1 至 m 编号。
[input]
输入的第一行是三个整数,分别代表n,m 和e。
接下来 e 行,每行两个整数 u,v,表示存在一条连接左部点 u 和右部点 v 的边。
[output]
输出一行一个整数,代表二分图最大匹配的边数。
1≤n,m≤500。
1≤e≤5×10^4。
1≤u≤n,1≤v≤m。
(保证给出的图没有重边)
[solved]
int n1,n2,m;
const int N=510;
const int M=50010;
struct edge{
int v,ne;
}e[M];
int h[N],idx;
int match[N];
bool vis[N];
void add(int u,int v){
e[++idx]={v,h[u]};
h[u]=idx;
}
int find(int x){
for(int i=h[x];i;i=e[i].ne){
int y=e[i].v;
if(!vis[y]){
vis[y]=1;
if(!match[y]||find(match[y])){
match[y]=x;
return true;
}
}
}
return false;
}
void solve(){
cin>>n1>>n2>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
add(x,y);
}
int res=0;
for(int i=1;i<=n1;i++){
memset(vis,0,sizeof(vis));
if(find(i)) res++;
}
cout<<res<<endl;
}