Kindergarten POJ - 3692

In a kindergarten, there are a lot of kids. All girls of the kids know each other and all boys also know each other. In addition to that, some girls and boys know each other. Now the teachers want to pick some kids to play a game, which need that all players know each other. You are to help to find maximum number of kids the teacher can pick.

Input

The input consists of multiple test cases. Each test case starts with a line containing three integers
GB (1 ≤ GB ≤ 200) and M (0 ≤ M ≤ G × B), which is the number of girls, the number of boys and
the number of pairs of girl and boy who know each other, respectively.
Each of the following M lines contains two integers X and Y (1 ≤ X≤ G,1 ≤ Y ≤ B), which indicates that girl X and boy Y know each other.
The girls are numbered from 1 to G and the boys are numbered from 1 to B.

The last test case is followed by a line containing three zeros.

Output

For each test case, print a line containing the test case number( beginning with 1) followed by a integer which is the maximum number of kids the teacher can pick.

Sample Input
2 3 3
1 1
1 2
2 3
2 3 5
1 1
1 2
2 1
2 2
2 3
0 0 0
Sample Output
Case 1: 3
Case 2: 4

题意:男生全部认识,女生全部认识,一些女生认识一些男生,找到一个集合,让所有的人都互相认识。

也就是最大团。

也就是求这个图的补图的最大独立集。

最大独立集就是 :所有点 - 最小点覆盖。

最小点覆盖也就是二分图匹配。


最少点覆盖就是二分图匹配。

最少边覆盖就是:所有点 - 二分图。

最大独立集: 所有点 -  二分图匹配。(独立集就是 这个集合中 所有的点都不连接)



#include <bits/stdc++.h>
using namespace std;
bool used[300];
int g[300][300];
int G,B,m,match[300];

int dfs(int v){
    for (int i = 1; i <= B; i++)
        if (g[v][i]==0 && !used[i]) //找补图,这个是一个求最大团,也就是找一个补图的最大独立集。
        {
            used[i] = 1;
            if (!match[i] || dfs(match[i]))  // 找增广路;
            {
                match[i] = v;
                return 1;
            }
        }
        return 0; //匈牙利算法要返回一个 假
}
int big_matching(){
    int res = 0;
    memset(match,0,sizeof(match));
    for (int i = 1; i <= G; i++){
            memset(used,0,sizeof(used));
            if (dfs(i)) res++;
    }
    return res; //这个函数最重要的就是要返回这个值。。。。!!!!!!!
}
int main() {
    int x,y;
    int num=1;
    while(scanf("%d%d%d",&G,&B,&m) == 3){
        if (G == 0) break;
        memset(g,0,sizeof(g));
        for (int i = 0; i < m; i++){
            scanf("%d%d",&x,&y);
            g[x][y] = 1;
        }
        int ans = big_matching();
        printf("Case %d: %d\n",num++,G+B-ans);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/kidsummer/article/details/80254232