题意:已知班级有g个女孩和b个男孩,所有女生之间都相互认识,所有男生之间也相互认识,给出m对关系表示哪个女孩与哪个男孩认识。现在要选择一些学生来组成一个团,使得里面所有人都认识,求此团最大人数。
思路:最大团问题。
定理:
原图的最大团=补图的最大独立集
原图的最大独立集=补图的最大团。
由于这个题的补图显然是一个二分图,而二分图的补图的最大独立集可以由匈牙利算法求的,所以该题的最大团问题可以转化成补图的最大独立集来做。
代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 using namespace std; 5 const int maxnum=201; 6 bool array[maxnum][maxnum]; 7 bool use[maxnum]; 8 int res[maxnum]; 9 int b,g,m; 10 11 bool find(int i) 12 { 13 int j; 14 for(j=1;j<=b;j++) 15 { 16 if(!use[j] && array[i][j]) 17 { 18 use[j]=true; 19 if(res[j]==0 || find(res[j])) 20 { 21 res[j]=i; 22 return true; 23 } 24 } 25 } 26 return false; 27 } 28 29 int main() 30 { 31 int p,q; 32 int i,ans; 33 int k=0; 34 while(scanf("%d%d%d",&g,&b,&m)!=EOF) 35 { 36 if(g==0 && b==0 && m==0) 37 break; 38 memset(array,true,sizeof(array)); 39 memset(res,0,sizeof(res)); 40 for(i=0;i<m;i++) 41 { 42 scanf("%d%d",&p,&q); 43 array[p][q]=false; //补图 44 } 45 ans=0; 46 for(i=1;i<=g;i++) 47 { 48 memset(use,false,sizeof(use)); 49 if(find(i)) 50 ans++; 51 } 52 k++; 53 printf("Case %d: %d\n",k,b+g-ans); 54 } 55 return 0; 56 }