最大团=补图的最大独立集

hdu2458

题意:给定G(G <= 200)个女孩和B(B <= 200)个男孩,以及M(0 <= M <= G*B)条记录(x, y)表示x号女孩和y号男孩互相认识。并且所有的女孩互相认识,所有的男孩互相认识,求找到最大的一个集合使得所有人都认识。

即求图的最大完全子图(最大团),那么可以转化为求补图的最大独立集(集合中的任意两点没有边相邻),而补图正好是一个二分图,二分图的最大独立集 = 顶点数 - 最大匹配

 1 //求最大独立集
 2 #include <stdio.h>
 3 #include <string.h>
 4 const int N = 222;
 5 int G,B,m;
 6 int Map[N][N];
 7 bool vis[N];
 8 int cx[N],cy[N];
 9 
10 bool dfs(int u)
11 {
12     int i;
13     for(i=1; i<=B; ++i)
14     {
15         if(!vis[i] && Map[u][i])
16         {
17             vis[i] = true;
18             if(cy[i] == -1 || dfs(cy[i]))
19             {
20                 cy[i] = u;
21                 cx[u] = i;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28 int MaxMatch()
29 {
30     memset(cx, -1, sizeof(cx));
31     memset(cy, -1, sizeof(cy));
32     int ans = 0;
33     for(int i=1; i<=G; ++i)
34     {
35         if(cx[i] == -1)
36         {
37             memset(vis, 0, sizeof(vis));
38             ans += dfs(i);
39         }
40     }
41     return ans;
42 }
43 int main()
44 {
45     int a,b,i;
46     int tCase = 1;
47     while(true)
48     {
49         scanf("%d%d%d",&G,&B,&m);
50         if(!G && !B && !m)
51             break;
52         memset(Map, 0, sizeof(Map));
53         for(i=1; i<=m; ++i)
54         {
55             scanf("%d%d",&a,&b);
56             Map[a][b] = 1;    
57         }
58         for(i=1; i<=G; ++i)
59             for(int j=1; j<=B; ++j)
60                 Map[i][j] = !Map[i][j];
61         int ans = MaxMatch();
62         printf("Case %d: %d
",tCase++,G + B - ans);
63     }
64 }
原文地址:https://www.cnblogs.com/justPassBy/p/4020460.html