题目链接:过山车
题目大意:几个男生和女生要去坐过山车,每个男生都有自己感兴趣的女生,他们要进行选择,问最多可以凑出几对
题目思路:这是一个典型的二分图匹配,使用匈牙利算法即可解决
匈牙利算法,分为两个过程,首先是匹配过程,其次是查找过程
匹配过程:
int match()
{
int ans=0;
for(int i=1;i<=a;i++){
memset(used,false,sizeof(used));
if(Find(i)) ans++;
}
return ans;
}
循环一次男生人数,每次为男生去匹配女生若可以匹配到,则ans++
查找过程:
bool Find(int x)
{
for(int i=1;i<=b;i++){
if(Map[x][i]&&!used[i]){
used[i]=true;
if(!nxt[i]||Find(nxt[i])){
nxt[i]=x;
return true;
}
}
}
return false;
}
先扫描一遍女生,如果男生感兴趣,并且该妹子尚未被标记过,那么标记该妹子,再通过nxt数组看看这个妹子是否名花有主,或者通过递归,看能不能把之前跟这个妹子匹配的男生换个妹子交往,如果可以的话,我们就可以把这个妹子交给这个男生了,即在nxt数组中进行更新,要是最终也没能找到,就返回false,最终输出ans
附上一个讲的更好的博客:趣写算法系列之--匈牙利算法
AC代码:
#include
using namespace std;
bool Map[505][505],used[505];
int nxt[505];
int m,a,b;
bool Find(int x)
{
for(int i=1;i<=b;i++){
if(Map[x][i]&&!used[i]){
used[i]=true;
if(!nxt[i]||Find(nxt[i])){
nxt[i]=x;
return true;
}
}
}
return false;
}
int match()
{
int ans=0;
for(int i=1;i<=a;i++){
memset(used,false,sizeof(used));
if(Find(i)) ans++;
}
return ans;
}
int main()
{
while(cin>>m&&m){
scanf("%d%d",&a,&b);
memset(Map,false,sizeof(Map));
memset(nxt,0,sizeof(nxt));
while(m--){
int u,v;
scanf("%d%d",&u,&v);
Map[u][v]=true;
}
cout<