二分匹配核心算法:匈牙利算法(增广路算法)
注意:匈牙利算法 也适用于 没有奇环的 一般图的 最大匹配
复杂度: O ( V ∗ E ) O(V*E) O(V∗E)
飞行员配对方案问题
匈牙利算法模板题:二分图上求最大匹配数
#include "bits/stdc++.h"
using namespace std;
inline int read() {int x=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9'))c=getchar();if(c=='-')f=-1,c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return f*x;}
const int maxn = 3e5+7;
int n, m;
int head[maxn], to[maxn], nxt[maxn], tot;
int vis[maxn], link[maxn], flag=1;
inline void add_edge(int u, int v) {
++tot; to[tot]=v; nxt[tot]=head[u]; head[u]=tot;
}
bool find(int u) {
for(int i=head[u]; i; i=nxt[i]) {
int v=to[i];
if(vis[v]==flag) continue;
vis[v]=flag;
if(!link[v]||find(link[v])) {
link[v]=u;
return 1;
}
}
return 0;
}
int main() {
m=read(), n=read();
int u, v;
while(scanf("%d%d", &u, &v), u!=-1||v!=-1) add_edge(u,v);
int cnt=0;
for(int i=1; i<=m; ++i, ++flag) if(find(i)) cnt++;
printf("%d\n", cnt);
for(int i=m+1; i<=m+n; ++i)
if(link[i]) printf("%d %d\n", link[i], i);
}
二分匹配知识点
- 最大匹配数=最小点覆盖
- 最小路径覆盖=最大独立集
- 最大匹配数+最大独立集=V
常见模型
- 在二维平面上将坐标按X,Y当做两个分图, 而坐标则看作分图之间的边;
- 有时需要重建X,Y的定义,如HDOJ 1045
- 其他类型动动脑子就好。