二分图匹配

Posted hbxblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分图匹配相关的知识,希望对你有一定的参考价值。

先来看看一道题目:二分图匹配

题目描述

给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

输入格式:

第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

输出格式:

共一行,二分图最大匹配

输入样例

1 1 1
1 1

输出样例:

1


这道题很明显是一个二分图匹配
普通人: 废话标题就是这个,不是二分图匹配是什么
dalao: 这不网络流裸题吗,随随便便就过了
小蒟蒻(me) 不要在意那么多细节,模板就当模板做就可以了


好了不管这么多了,接下来进入正题

知道二分图的往下看
不知道的请移步这里二分图什么是二分图(你不知道二分图来这儿干啥?请移步这儿)

首先介绍一下什么是二分图

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
来自百度百科,虽然看不,懂不过没关系,能看到这里说明你已经初步掌握了二分图
请过了下片这题再来看本博文
二分图染色

接下来把问题具体化一下

一直现在有n个男孩和m个女孩,两两组队参加舞会,已知第i个男孩和第j个互相有好感.现在要使得最多的人可以参加舞会

技术分享图片

现在4个男孩,4个女孩,我们现在来由图片一个一个看
首先鸣人发现小樱没有人选,于是选了小樱去舞会
接下来二柱子来了,发现小樱尽然被选了,十分气愤,于是去看看谁选了小樱,结果发现是鸣人选了,于是愤怒全消了,凭借他们两个的基情,呸呸呸友情,这点小事算什么,反正我还有雏田,于是佐助选了小樱,鸣人选了雏田
然后李洛克来了,他也十分喜欢小樱,想和小樱去舞会,可是我们的二柱子还在那里啊,知道了这个消息之后十分气愤说:你又不是鸣人,况且我只有小樱了,给你了,我干什么去?于是李洛克十分伤心,但是突然发现天天还在,而前冇的人选,于是李洛克和天天组成了一对去舞会
突然路飞不知道从哪里跑到火影来了,看到了小樱,于是一千钟情,海贼王都不做了,就想和小樱一起去参加舞会,二柱子不干了,和路飞打了一场,路飞不敌灰溜溜的走了
现在已经有三个对匹配了,这明显是最大的匹配数量了,只剩下凤姐和路飞了,当路飞看到凤姐后,就大喊:我要回去,我是要当海贼王的男人(俺は海賊王になる男だ)

应该差不多理解吧

#include<bits/stdc++.h>
#define rg register
using namespace std;
typedef long long ll;
inline int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9')  f= (c=='-')?-1:1,c=getchar();
    while(c>='0'&&c<='9')  x=x*10+c-48,c=getchar();
    return f*x;
}
int n,m,e,u,v,cnt,head[10001],f[10001],bj[10001],ans;
struct node{
    int to,next;
}a[2000001];
void add(int x,int y){
    a[++cnt].to=y;
    a[cnt].next=head[x];
    head[x]=cnt;
}
int dfs(int u){
    for(int i=head[u];i;i=a[i].next){
        int v=a[i].to;
        if(f[v])
            continue;
        f[v]=1;
        if(!bj[v]||dfs(bj[v])){
            bj[u]=v;
            bj[v]=u;
            return 1;
        }
    }
    return 0;
}
int main(){
    n=read(),m=read(),e=read();
    for(int i=1;i<=e;i++){
        u=read(),v=read();
        if(v>m)
            continue;
        add(u,v+n);
        add(v+n,u);
    }
    for(int i=1;i<=n;i++){
        memset(f,0,sizeof(f));
        if(dfs(i))
            ans++;
    }
    printf("%d",ans);
}

以上是关于二分图匹配的主要内容,如果未能解决你的问题,请参考以下文章

二分图匹配(模板)

HDU 2236 无题II(二分图匹配+二分)

二分图——匈牙利算法简述

HDU - 1083 Courses(二分图匹配)

匈牙利算法-二分图的最大匹配

洛谷P3386——二分图匹配