二分图匹配(持续更新)

二分匹配核心算法:匈牙利算法(增广路算法)

注意:匈牙利算法 也适用于 没有奇环的 一般图的 最大匹配

复杂度: O ( V ∗ E ) O(V*E) O(VE)

飞行员配对方案问题
匈牙利算法模板题:二分图上求最大匹配数

#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);
}

二分匹配知识点

  1. 最大匹配数=最小点覆盖
  2. 最小路径覆盖=最大独立集
  3. 最大匹配数+最大独立集=V

常见模型

  1. 在二维平面上将坐标按X,Y当做两个分图, 而坐标则看作分图之间的边;
  2. 有时需要重建X,Y的定义,如HDOJ 1045
  3. 其他类型动动脑子就好。

你可能感兴趣的:(算法(Lazy))