题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2063、
解题思路:
二分图最大匹配。
匈牙利算法即可解决,但是注意的是男生和女生数目不相等,所以需要用少的去挑多的。
代码如下:
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
#define N 1010
#define M 510
#define max(a, b) a > b ? a : b
#define min(a, b) a < b ? a : b
int head[M], next[N], key[N], num;
int match[M];
bool use[M];
void add(int u, int v) //hash表存图
{
key[num] = v;
next[num] = head[u];
head[u] = num++;
}
bool find(int u) //匈牙利算法
{
int temp;
for(int i = head[u]; i != -1; i = next[i])
{
temp = key[i];
if(!use[temp])
{
use[temp] = true;
if(match[temp] == -1 || find(match[temp])) //增广路
{
match[temp] = u;
return true;
}
}
}
return false;
}
int sum(int n, int m) //n是人少的,m是人多的
{
int sumall = 0;
for(int i = 1; i <= m; ++i)
{
memset(use, false, sizeof(use));
if(find(i))
sumall++;
}
return sumall;
}
int main()
{
int relation, boy, girl, max1, min1;
int u, v;
while(scanf("%d", &relation) && relation)
{
num = 0;
memset(head, -1, sizeof(head));
memset(match, -1, sizeof(match));
scanf("%d%d", &boy, &girl);
min1 = min(boy, girl);
max1 = max(boy, girl);
for(int i = 0; i < relation; ++i)
{
scanf("%d%d", &u, &v);
add(u, v);
}
printf("%d\n", sum(min1, max1)); //少的挑多的
}
return 0;
}