题目大意如下:幼稚园里有m个男孩和n个女孩(m、n防伪都是[1,200]),男孩之间都相互认识,女孩之间也相互认识,另外有部分男孩和女孩也认识。现在要举办一个活动,选取一些同学,要求所有选取的同学之间两两相互认识。
显然,这是一个最大团问题。普通图的最大团问题是NP的,但是这个题目的特殊性在于m和n个顶点之间均连边,因此想到求它的补图的最大独立集。显然它的补图是一个二分图,求二分图可以任意选取方法,最大流和匈牙利应该都能过。
一下是我写的匈牙利:
- bool bg[201][201],visited[201];
- int match[201],ans,g,b;
- bool augement(int x)
- {
- for (int i=1;i<=b;++i)
- {
- if (bg[x][i] && !visited[i])
- {
- visited[i]=true;
- if (match[i]==0 || augement(match[i]))
- {
- match[i]=x;
- return true;
- }
- }
- }
- return false;
- }
- int main()
- {
- int m,a,bb,ant=0;
- while (scanf("%d%d%d",&g,&b,&m))
- {
- if (!g && !b && !m) break;
- ++ant;
- for (int i=1;i<=g;++i) for(int j=1;j<=b;++j) bg[i][j]=true;
- memset(match,0,sizeof match);
- ans=0;
- while (m--)
- {
- scanf("%d%d",&a,&bb);
- bg[a][bb]=false;
- }
- for (int i=1;i<=g;++i)
- {
- memset(visited,0,sizeof visited);
- if (augement(i)) ++ans;
- }
- printf("Case %d: %d/n",ant,g+b-ans);
- }
- return 0;
- }