hdu 2063

本篇文章借鉴其他大神的代码,在此只是做一些批注,以便自己记忆和他人理解。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
/**输入数据的第一行是三个整数K , M , N,
分别表示可能的组合数目,女生的人数,男生的人数。
0<K<=1000 1<=N 和M<=500.
接下来的K行,每行有两个数,分别表示女生Ai愿意和男生Bj做partner。
最后一个0结束输入。****/
# define Manx 501
bool match_will[Manx][Manx];
bool used[Manx];
int match[Manx];
int k,m,n;
bool discover(int x);
int main()
{
    while (~scanf("%d",&k))
  {
    if (k==0) break;
    cin>>m>>n;
    for(int i=0;i<Manx;i++)
    {
        memset(match_will[i],0,sizeof(match_will[i]));
        memset(match,0,sizeof(match));//初始化
    }
    int a,b;
    for(int i=0;i<k;i++)
       {
           cin>>a>>b;
           match_will[a][b]=1;//记录可匹配的组合数
       }
    int cnt=0;//记录组合数目
    for(int i=1;i<m+1;i++)//之所以从i=1开始,是因为之后的输入配对是直接从1开始的
    {
        memset(used,0,sizeof(used));
        if (discover(i)) cnt+=1;
    }
    cout<<cnt<<endl;
  }
    return 0;
}
bool discover(int x)
{
    for(int i=1;i<n+1;i++)
    {
        if(match_will[x][i]&&used[i]==0)
        {
            used[i]=1;
            if(match[i]==0||discover(match[i]))
            {
                match[i]=x;
                return 1;
            }
        }
    }
    return 0;

}

代码源网络,侵删。

下为个人理解

1. 首先,完成输入。

K,M,N很好理解和解决。

愿意进行的匹配记录,选用逻辑性数组。

2. 进行匹配

女生固定,遍历男生。

遍历成功的条件,可匹配;

                          若未与其他女生匹配过,直接输出+1;

                          若与其他女生匹配过,那么递归之前的女生是否还能与其他男生匹配,此时需要对男生进行标记,选用used数组,以防三人行或者多人行出现。如果之前的女生还能与其他男生匹配,那么匹配数+1,若不行,则下一个男生。


猜你喜欢

转载自blog.csdn.net/sinat_36420785/article/details/80105137