二分图是一个图
它的顶点可以分为两个独立的集合
u
和v
,这样每一条边(u,v)
要么从u
到v
连接一个顶点,要么从v
到u
连接一个顶点。换句话说,对于每一条边(u,v)
,要么u
属于u
,要么v
属于v
,或者u
属于v
,v
属于u
,也可以说没有边连接同一集合的不同点。
//match[j]=a,表示女孩j的现有配对男友是a
//st[]数组我称为临时预定数组,st[j]=a表示一轮模拟匹配中,女孩j被男孩a预定了。
#include <bits/stdc++.h>
using namespace std;
const int N=510;
vector<int> v[N];
int n1,n2,m;
int match[N];
bool st[N];
bool find(int x)
{
for(auto u:v[x])//遍历自己喜欢的女孩
{
if(!st[u])//如果在这一轮模拟匹配中,这个女孩尚未被预定
{
st[u]=true;//那x就预定这个女孩了
if(!match[u]||find(match[u]))
{
//如果女孩j没有男朋友,或者她原来的男朋友能够预定其它喜欢的女孩。
match[u]=x;
return true;
}
}
}
return false;//自己中意的全部都被预定了。配对失败。
}
int main()
{
cin>>n1>>n2>>m;
while(m--)
{
int a,b;cin>>a>>b;
v[a].push_back(b);
}
int res=0;
for(int i=1;i<=n1;i++)
{
memset(st,false,sizeof st); //因为每次模拟匹配的预定情况都是不一样的所以每轮模拟都要初始化
if(find(i)) res++;
}
cout<<res;
}
st数组的理解:
为什么要memset (st , false ,sizeof st) !!!
每个男生都有机会追求所有自己有好感的女生,即使她现在有男朋友。
算法模拟的过程👇