Description
Input
G, B (1 ≤ G, B ≤ 200) and M (0 ≤ M ≤ G × B), which is the number of girls, the number of boys and
the number of pairs of girl and boy who know each other, respectively.
Each of the following M lines contains two integers X and Y (1 ≤ X≤ G,1 ≤ Y ≤ B), which indicates that girl X and boy Y know each other.
The girls are numbered from 1 to G and the boys are numbered from 1 to B.
The last test case is followed by a line containing three zeros.
Output
Sample Input
Sample Output
Case 1: 3 Case 2: 4
独立集:任意两点都不相连的顶点的集合
独立数:独立集中顶点的个数
完全子图:任意两点都相连的顶点的集合
最大完全数:最大完全子图中顶点的个数
最大完全数=原图的补图的最大独立数
最大独立数=顶点数-最大匹配数
本题是要求图中的最大完全子图(最大团)中顶点的个数。
由于原图的补图是一个二分图,其最大完全数等价于其补图的最大独立集中元素的个数,
于是可以根据二分图的性质求出这个最大独立集。而普通图的最大团则是一个NP问题。
反过来建图,建立不认识的图,就变成求最大独立集了。
#include<iostream>
#include<string.h>
using namespace std;
int G,B,M;
int map[210][210],visited[210],p[210];
bool findpath(int x)
{
for(int i=1;i<=B;i++)
{
if(!visited[i]&&map[x][i]==1)
{
visited[i]=1;
if(!p[i]||findpath(p[i]))
{
p[i]=x;
return true;
}
}
}
return false;
}
int main()
{
int cases=1;
while(cin>>G>>B>>M)
{
if(G==0&&B==0&&M==0)
break;
int i,j,x,y,sum=0;
for(i=0;i<=G;i++)
for(j=0;j<=B;j++)
map[i][j]=1;
memset(p,0,sizeof(p));
for(i=1;i<=M;i++)
{
cin>>x>>y;
map[x][y]=0;
}
for(i=1;i<=G;i++)
{
memset(visited,0,sizeof(visited));
if(findpath(i))
sum++;
}
sum=G+B-sum;
cout<<"Case "<<cases++<<": "<<sum<<endl;
}
return 0;
}