题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3829
求二分图最大独立集, 可以转化为最大匹配问题;
附上代码:
1 #include <cstdio> 2 #include <string> 3 #include <cstring> 4 #include <iostream> 5 using namespace std; 6 7 #define MAX (500 + 8) 8 int map[MAX][MAX]; 9 int n, m, p; 10 string cat[MAX][5], dog[MAX][5]; 11 int mk[MAX]; 12 //从X集合中的顶点u出发用深度优先的策略寻找增广路 13 //(这种增广路只能使当前的匹配数增加1) 14 int nx,ny; //X和Y集合中顶点的个数 15 int cx[MAX],cy[MAX]; 16 //cx[i]表示最终求得的最大匹配中与Xi匹配的Y顶点, cy[i]同理 17 int path(int u) 18 { 19 for(int v=1; v<=ny; v++) //考虑所有Yi顶点v 20 { 21 if(map[u][v]&&!mk[v]) 22 { 23 mk[v]=1; 24 //如果v没有匹配,或者如果v已经匹配了, 25 //但从cy[v]出发可以找到一条增广路 26 if(cy[v]==-1|| path(cy[v])) 27 { 28 cx[u] = v; //把v匹配给u 29 cy[v] = u; //把u匹配给v 30 return 1; //找到可增广路 31 } 32 } 33 } 34 return 0 ; //如果不存在从u出发的增广路 35 } 36 int MaxMatch() //求二部图最大匹配的匈牙利算法 37 { 38 int res=0; 39 memset(cx,0xff,sizeof(cx)); //从0匹配开始增广 40 memset(cy,0xff,sizeof(cy)); 41 for(int i=1; i<=nx; i++) 42 { 43 if(cx[i]==-1) //从每个未盖点出发进行寻找增广路 44 { 45 memset(mk,0,sizeof(mk)); 46 res+=path(i); //每找到一条增广路,可使得匹配数加1 47 } 48 } 49 return res; 50 } 51 52 int main(void) { 53 while(~scanf("%d %d %d", &n, &m, &p)) { 54 nx = ny = 1; 55 for (int i = 1; i <= p; i++) { 56 string a, b; 57 cin >> a >> b; 58 if (a[0] == 'C') { 59 cat[nx][0] = a[]; 60 cat[nx][1] = b; 61 nx++; 62 } 63 if (a[0] == 'D') { 64 dog[ny][0] = a; 65 dog[ny][1] = b; 66 ny++; 67 } 68 } 69 //nx=n;ny=n; 70 nx--; 71 ny--; 72 memset(map,0,sizeof(map)); 73 for(int i = 1; i <= nx; i++) { 74 for (int j = 1; j <= ny; j++) { 75 if (cat[i][0] == dog[j][1] || cat[i][1] == dog[j][0]) 76 map[i][j] = 1; 77 } 78 } 79 int max=MaxMatch(); 80 printf("%d ", p - max); 81 } 82 83 return 0; 84 }