POJ 3692:Kindergarten(最大團)

Kindergartenios

Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 4920 Accepted: 2399spa

Descriptioncode

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.three

Inputip

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 ≤ 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.input

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

Outputit

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.io

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 0ast

Sample Output
Case 1: 3
Case 2: 4

題意:幼兒園裏男孩紙跟男孩紙認識,女孩紙跟女孩紙認識,男孩紙跟女孩紙也部分認識。

須要求出最大的,能使裏面全部男孩紙女孩紙都認識的集合(最大團)

1.獨立集:任意兩點都不相連的頂點的集合

2.定理:最大獨立集=頂點數-最大匹配邊

3.徹底子圖:任意兩點都相連的頂點的集合(最大徹底子圖即最大團)

4.定理:最大團=原圖補圖的最大獨立集=頂點數-最大匹配數
注意,要反向建圖(把認識的變成不認識的,不認識的成爲認識的,這樣才能求補圖)

01.#include<cstdio>  
02.#include<cstring>  
03.#include<algorithm>  
04.#include<iostream>  
05.  
06.using namespace std;  
07.  
08.const int M = 1000 + 5;  
09.int k, m, n;  
10.int link[M];  
11.bool MAP[M][M];  
12.bool cover[M];  
13.int ans;  
14.int cas=0;  
15.  
16.void init()  
17.{  
18.    int x, y;  
19.    memset(MAP, true, sizeof(MAP));  
20.    for(int i=1; i<=k; i++)  
21.    {  
22.        scanf("%d%d", &x, &y);  
23.        MAP[x][y]=false;  
24.    }  
25.}  
26.  
27.bool dfs(int x)  
28.{  
29.    for(int y=1; y<=m; y++)  
30.    {  
31.        if(MAP[x][y] && !cover[y])  
32.        {  
33.            cover[y]=true;  
34.            if(!link[y] || dfs(link[y]))  
35.            {  
36.                link[y]=x;  
37.                return true;  
38.            }  
39.        }  
40.    }  
41.    return false;  
42.}  
43.  
44.int main()  
45.{  
46.    while(scanf("%d%d%d", &n, &m, &k) && n && m && k)  
47.    {  
48.        cas++;  
49.        ans=0;  
50.        init();  
51.        memset(link, false, sizeof(link));  
52.        for(int i=1; i<=n; i++)  
53.        {  
54.            memset(cover, 0, sizeof(cover));  
55.            if( dfs(i) )  
56.                ans++;  
57.        }  
58.        printf("Case %d: %d\n", cas,(n+m)-ans);  
59.    }  
60.  
61.    return 0;  
62.}
相關文章
相關標籤/搜索