【Algothrim】Christmas Gifts

来源:互联网 发布:阿里云域名使用方法 编辑:程序博客网 时间:2024/05/17 21:44


The company has decided to give presents to all the employees for Christmas.
Each employee has a preferred gift, but unfortunately each gift is available in only one unit. Every person should choose only one.
If the first person chooses the first gift, the second person cannot now choose the first one because it has been taken.
Everyone would rather give up their gift than take an unwanted gift. That means they won’t take the gift unless it is the one they want.


The department responsible wants to create the maximum number of satisfied people with their desired gifts.
When the number of people and their preferred gifts are given, what do you do to get the maximum number of people with their desired gifts?

Time limit : 2 sec (Java : 4 sec)


[Input]
There can be more than one test case in the input file. The first line has T, the number of test cases.
Then the totally T test cases are provided in the following lines (T ≤ 10 )


In each test case,
The number of people, N, and the number of gifts, M, are given in order at the first row. (0 ≤ N, M ≤ 200)
The number of gifts of each person's preference, Si, and its numbers are given from the second row through row of N. (0 ≤ Si ≤ M)


[Output]
For each test case, you should print "Case #T" in the first line where T means the case number. For each test case, you should output the number of people who choose the right gift for them when you link as many gifts chosen as possible at the first row.


[I/O Example]

Input
2
5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2
10 10
3 1 7 8
3 5 9 10
3 3 6 10
3 5 6 9
3 4 5 8
3 1 8 10
2 3 8
2 4 8
3 2 3 6
3 4 6 7


Output

Case #1

4

Case #2

10


[Explanation of an example1]
If the first person chooses the fifth gift, the second person chooses the fourth,
the third person chooses the first, and the fourth person chooses the second, everyone can choose a gift except the fifth person.


参考资料

http://blog.csdn.net/pi9nc/article/details/11848327

http://www.open-open.com/code/view/1435717975575

http://blog.csdn.net/dark_scope/article/details/8880547

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。


#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXN 202int g[MAXN][MAXN];int link[MAXN];int choosed[MAXN];int M;//giftsint N;//employeesint A;int dfs(int n){int m;for (m = 1; m <= M; m++)//遍历右边每一个点{if (g[n][m] && !choosed[m])//有连接,且可以连接{choosed[m] = 1;//用掉这个右边的点if (link[m] == 0 || dfs(link[m]))
//link[m]==0成立,表示没和左边的点连过,就可以直接连上;如果不成立,给link[m]匹配的点n重新找个点,能找到,就把m让出来,不能找到那m就失败了{link[m] = n;return 1;}}}return 0;}int hungary(){int rst = 0;int n;memset(link, 0, sizeof(link));for (n = 1; n <= N; n++)//遍历左边每个点,为其找右边的点{memset(choosed, 0, sizeof(choosed));if (dfs(n)){rst++;}}return rst;}int main(void){int t, T;int i, j;int tmp1,tmp2;freopen("ChristmasGifts.txt", "r", stdin);setbuf(stdout, NULL);scanf("%d", &T);for (t = 1; t <= T; t++){scanf("%d %d", &N, &M);if (N == 0 || M == 0){A = 0;scanf("%d", &tmp1);goto END;}memset(g, 0, sizeof(g));//memset(link, 0, sizeof(link));//memset(choosed, 0, sizeof(choosed));A = 0;for (i = 1; i <= N; i++){scanf("%d", &tmp1);for (j = 1; j <= tmp1; j++){scanf("%d", &tmp2);g[i][tmp2] = 1;}}if (M == 1 && N > 0){for (i = 1; i < N; i++){if (g[i][1] == 1){A = 1;goto END;}}}A = hungary();END:printf("Case #%d\n", t);printf("%d\n", A);}return 0;}

0 0
原创粉丝点击