本篇文章借鉴其他大神的代码,在此只是做一些批注,以便自己记忆和他人理解。
#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,若不行,则下一个男生。