HDU 5090--Game with Pearls【二分图最大匹配】

Game with Pearls

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1916    Accepted Submission(s): 672


Problem Description
Tom and Jerry are playing a game with tubes and pearls. The rule of the game is:

1) Tom and Jerry come up together with a number K.

2) Tom provides N tubes. Within each tube, there are several pearls. The number of pearls in each tube is at least 1 and at most N.

3) Jerry puts some more pearls into each tube. The number of pearls put into each tube has to be either 0 or a positive multiple of K. After that Jerry organizes these tubes in the order that the first tube has exact one pearl, the 2nd tube has exact 2 pearls, …, the Nth tube has exact N pearls.

4) If Jerry succeeds, he wins the game, otherwise Tom wins.

Write a program to determine who wins the game according to a given N, K and initial number of pearls in each tube. If Tom wins the game, output “Tom”, otherwise, output “Jerry”.
 

Input
The first line contains an integer M (M<=500), then M games follow. For each game, the first line contains 2 integers, N and K (1 <= N <= 100, 1 <= K <= N), and the second line contains N integers presenting the number of pearls in each tube.
 

Output
For each game, output a line containing either “Tom” or “Jerry”.
 

Sample Input
 
   
2 5 1 1 2 3 4 5 6 2 1 2 3 4 5 5
 

Sample Output
 
   
Jerry Tom
 
题目大意:
Tom和Jerry做游戏,给定N个管子,每个管子上面有一定数目的珍珠。
现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放。
最后将管子排序,如果可以做到第i个管子上面有i个珍珠,则Jerry胜出,反之Tom胜出。

思路:
对于第i个管道,若它里面有a个珍珠,我们可以枚举出它可以达到的所有合法状态(就是管道里面的珍珠不能多于N个),并将该管道与该状态建边。然后匈牙利跑一次最大匹配,看匹配值是不是N即可。(因为共有N个状态,当N个管道全部匹配的时候,说明它们匹配的状态全都不一样,这样可以说明这个时候N个状态全部达到了)


以4 3 1 1 2 3为样例。
1 可以变成 {1,4}
1 可以变成 {1,4}
2 可以变成{2}
3 可以变成{3}
如果从集合{1,1,2,3}到集合{1,2,3,4}的最大匹配数为N,则代表这两两匹配,Jerry胜出,否则Tom胜出。

#include 
#include 
#include 
#include 
#include 
#include 
#define maxn 200
using namespace std;
int map[maxn][maxn];
int link[maxn];
int used[maxn];
int n, k;

int dfs(int x){
    for(int i = 1; i <= n; ++i){
        if(map[x][i] && !used[i]){
            used[i] = 1;
            if(link[i] == -1 || dfs(link[i])){
                link[i] = x;
                return true;
            }
        }
    }
    return false;
}

int hungary(){
    int ans = 0;
    memset(link, -1, sizeof(link));
    for(int j = 1; j <= n; ++j){
        memset(used, 0, sizeof(used));
        if(dfs(j))
            ans++;
    }
    return ans;
}

int main (){
    int T;
    int num;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &k);
        memset(map,0,sizeof(map));
        for(int i = 1; i <= n; ++i){
            scanf("%d", &num);
            while(num <= n){
                map[num][i] = 1;
                num += k;
            }
        }
        int sum = hungary();
        if(sum == n)
            printf("Jerry\n");
        else
            printf("Tom\n");
    }
    return 0;
}


你可能感兴趣的:(二分图)