HDU-2063 过山车 (二分图匹配)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063
题意:
m个女生和n个男生去坐过山车,每个女生有自己想要搭配的男生(0个或者多个),一个女生最多和一个男生搭配,只有搭配成功的男女可以去坐过山车,求最多可以有多少对男女可以坐上过山车。
题解:
二分图匹配裸题。
利用数组记录图上边的关系,对于每个女生遍历每个男生,若是这个男生和女生之间有边,且这个男生没有被别的女生配对,那么这两个人配对,如果这个男生已经配对过,那么向前递归该男生匹配的女生girl【i】,如果还有可以匹配的男生,那么放弃掉这个男生,换下一个男生。对于girl【i】的匹配与之前相同。
原则:
后来者居上,如果后来的人和前面的人可以匹配同一人,并且前面的人还可以匹配别的人,那么前面的人就要将自己之前的匹配对象让给后来的人,前面的人更换匹配对象,继续向前递归。
AC代码:

#include <bits/stdc++.h>
//#pragma GCC optimize(2)

using namespace std;

#define LL long long
#define Rint register int
#define U unsigned
#define forn(i,a,b) for(int i = a;i <= b;++i)
#define nfor(i,a,b) for(int i = a;i >= b;--i)
#define pii pair<int ,int>
#define MS0(X) memset(X,0,sizeof(X))
#define MSf(X) memset(X,false,sizeof(X))
#define MS1(X) memset(X,-1,sizeof(X))
#define BR printf("--------------------\n")
#define pb push_back
#define rep(i,a,b) for(Rint i=a;i<=b;++i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int maxn=505;

int n,k,m;
int mp[maxn][maxn];//记录女i和男j是否有边
int vis[maxn],girl[maxn];

int find_(int x)
{
    for(int i=1;i<=n;i++)
    {
        if(mp[x][i]==1&&!vis[i])
        {
            vis[i]=1;//标记此男生已被匹配
            if(girl[i]==0||find_(girl[i]))//第i个男生没被匹配过或者,之前匹配该男生的女生还可以匹配到别的女生
            {
                girl[i]=x;
                return 1;//新增加了一个匹配
            }
        }
    }
    return 0;
}

int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    while(cin>>k)
    {
        if(k==0)break;
        MS0(mp);
        MS0(girl);
        cin>>m>>n;
        for(int i=0;i<k;i++)
        {
            int u,v;
            cin>>u>>v;
            mp[u][v]=1;
        }
        int ans=0;
        for(int i=1;i<=m;i++)
        {
            MS0(vis);
            if(find_(i))
                ans++;
        }
        cout<<ans<<"\n";
    }
	return 0;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/102496984