首先,什么是二分图?
——二分图,顾名思义,就是由两个子集组成的特殊图论模型,如下图
可以将大写字母看作男生,将小写字母看作女生,则A男生与b女生之间有好感,且C男生与b女生之间也有好感。
那么,二分图匹配又有什么用?
——二分图匹配主要用于寻找增广路径的运算,接下来我们就来介绍一种算法:匈牙利算法!
比如说上图(还是那张恶心的图......),A男生与b女生之间有好感,可是男生与b女生之间也有好感,一个女生不可以有多个真爱,所以呢,先做A男生与b女生之间的判断时,先寻找一下有没有其他人可以与该女生搭配,如果无,则直接搭配(喜结良缘)!
如果有,则判断哪一个男生只有b女生可以搭配,就将哪一个进行搭配!
直接上代码吧!
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+5;
int a[maxn][maxn],match[maxn],p[maxn],n,m,e,ans;
bool dfs(int x){//x为当前男生
for(int j=1;j<=m;j++)//枚举每一个女生
if(!p[j] && a[x][j]){//假如该女生未访问过 而且 该男生与女生之间有连接
p[j]=1;
if(!match[j] || dfs(match[j]))//该女生还没有伴侣 或者 还可以找到其他伴侣
{
match[j]=x;//就存下当前的男生编号
return 1;
}
}
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&e);
for(int i=1;i<=e;i++)
{
int u,v;
scanf("%d%d",&u,&v);
a[u][v]=1;
}
for(int i=1;i<=n;i++){
memset(p,0,sizeof(p));
if(dfs(i))ans++;//挨个的枚举男生编号
}
printf("%d",ans);
return 0;
}