POJ 3692 Kindergarten (匈牙利 二分图)

Kindergarten
Time Limit: 2000MS
Memory Limit: 65536K
Total Submissions: 5009
Accepted: 2448

Description

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
G, B (1 ≤ G, B ≤ 200) and M (0 ≤ MG × 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

Source

2008 Asia Hefei Regional Contest Online by USTC

题目链接  :http://poj.org/problem?id=3692


题目大意: 有G个女孩和B个男孩,同性之间互相认识,而且有的男孩和女孩之间也互相认识。现在要选出来最多的孩子,他们之间都互相认识。


题目分析:  两两相互认识的反面就是那一组中全都互不认识,问题转化为求解最大独立集了。在构造二分图时,把全部人都初始化为相互认识,再把相互认识的初始化不认识的。然后用用匈牙利算法求出最大匹配,则最大独立集 = 全部顶点- 最大匹配。


#include <cstdio>
#include <cstring>
int const MAX = 200 + 1;
int vis[MAX*MAX];
int map[MAX][MAX];
int match[MAX];
int g, b;//g女生个数,b男生个数

int DFS(int u)
{
    for(int v = 1; v <= b; v++) //考虑所有代表男生的顶点
    {
        if(map[u][v] && !vis[v]) //如果uv邻接且未访问(即男女认识)
        {
            vis[v] = 1;     //访问v
            //若v没有匹配,或者v匹配了,可是从match[v]出发可以找到一条
            //增广路则将uv匹配
            if(match[v] == -1 || DFS(match[v]))
            {
                match[v] = u;
                return 1;
            }
        }
    }
    return 0;  //不存在从u出发的增广路
}

int hungary()  //匈牙利算法的DFS增广搜索
{
    int res = 0;
    memset(match,-1,sizeof(match));
    for(int u = 1; u <= g; u++)  //枚举女生编号
    {
        
        memset(vis,0,sizeof(vis));
        res += DFS(u);  //找到最大匹配
    }
    return res;
}
int main()
{
    int T = 0;
    int m, x, y;//m男女相互认识的对数 x女生编号,y男生编号,xy相互认识
    while(scanf("%d %d %d",&g, &b, &m) && (g+b+m))
    {
        memset(map,1,sizeof(map)); //初始化两两都认识
        for(int i = 0; i < m; i++)
        {
            scanf("%d %d",&x, &y);
            map[x][y] = 0;   //将输入的认识的转化为不认识的
        }
        //结果即最大独立集为图中的顶点数 - 最大匹配
        printf("Case %d: %d\n", ++T, g + b - hungary());
    }
}


你可能感兴趣的:(poj,图论,匈牙利算法,二部图最大匹配)