题意:幼儿园里男孩纸跟男孩纸认识,女孩纸跟女孩纸认识,男孩纸跟女孩纸也部分认识。
需要求出最大的,能使里面所有男孩纸女孩纸都认识的集合(最大团)
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
| #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; }
|