模板整理: 图论---二分图匹配


二分图要记住的性质:(n为点数)
二分图最大匹配=二分图最小点覆盖
=n-二分图最大点独立集
=n-二分图最小边覆盖
题型:求二分图匹配型;判断一张图是否为二分图(染色)型。

求二分图最大匹配的方法:匈牙利算法。
思路:找路增广……(网络流= =)
时间复杂度O( αn2 ), α 为一个比较小的常数。
实际题目里有些题n=4W也能跑过,所以稍微放点心。
模板:luogu3386
给出两个点集间的连边,求二分图最大匹配。

#include<bits/stdc++.h>
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int 
    N=1005;
int n,m,e;
int mp[N][N],match[N];
bool vis[N];
bool dfs(int u){
    int t;
    for (int i=1;i<=m;i++)
        if (mp[u][i] && !vis[i]){
            vis[i]=1;
            t=match[i];
            match[i]=u;
            if (!t || dfs(t))
                return 1;
            match[i]=t;
        }
    return 0;
} //增广
int main(){
    n=read(),m=read(),e=read();
    int u,v;
    for (int i=1;i<=e;i++){
        u=read(),v=read();
        if (u>n || v>m) continue;
        mp[u][v]=1;
    }
    int ans=0;
    for (int i=1;i<=n;i++){
        memset(vis,0,sizeof(vis));
        if (dfs(i)) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


注意能否增广也是一个重要的性质,
有些题就需要用到,比如bzoj1854

猜你喜欢

转载自blog.csdn.net/ThinFatty/article/details/78495816