二分图匹配-匈牙利算法(HDU-2063 过山车)

题目链接:过山车

题目大意:几个男生和女生要去坐过山车,每个男生都有自己感兴趣的女生,他们要进行选择,问最多可以凑出几对

题目思路:这是一个典型的二分图匹配,使用匈牙利算法即可解决

 

匈牙利算法,分为两个过程,首先是匹配过程,其次是查找过程

匹配过程:

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<

 

你可能感兴趣的:(模板例题)