0%

POJ3692 (最大完全子图)

题目链接

题意:幼儿园里男孩纸跟男孩纸认识,女孩纸跟女孩纸认识,男孩纸跟女孩纸也部分认识。

需要求出最大的,能使里面所有男孩纸女孩纸都认识的集合(最大团)

1.独立集:任意两点都不相连的顶点的集合

2.定理:最大独立集=顶点数-最大匹配边

3.完全子图:任意两点都相连的顶点的集合(最大完全子图即最大团)

4.定理:最大团=原图补图的最大独立集=顶点数-最大匹配数
注意,要反向建图(把认识的变成不认识的,不认识的成为认识的,这样才能求补图)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//2021-05-14 17:13:02
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int N = 501;
int e[N][N];
int match[N];
int G, B, M;
int vis[N];
int dfs(int u){
for(int v = 1; v <= B; v++){
if(!vis[v] && !e[u][v]){
vis[v] = 1;
if(match[v]==-1 || dfs(match[v]) ){
match[v] = u;
return 1;
}
}
}
return 0;
}


int main(){
int T = 0;
while(scanf("%d%d%d", &G, &B, &M)&&G&&B&&M){
memset(e, 0, sizeof(e));
memset(match, -1, sizeof(match));
for(int i = 1; i <= M; i++){
int x, y;
scanf("%d%d", &x, &y);
e[x][y] = 1;
}
int res = 0;
for(int i = 1; i <= G; i++){
memset(vis, 0, sizeof(vis));
if(dfs(i)){
res++;
}
}
printf("Case %d: %d\n", ++T, G+B-res);
}

return 0;
}

求大佬赏个饭