题目链接: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; }