poj3692_最大团_二分图

题意:已知班级有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 }

 

 

 

你可能感兴趣的:(poj)