又理解了一下二分图的匈牙利算法。关键的一点是执行匈牙利算法时,图的顶点应该被分成两个集合,所有边都规定为一个方向。
/*
* poj-1274
* mike-w
* 2012-11-04
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXN 222
#define LOL_DEBUG
int match[MAXN], tag[MAXN];
int f[MAXN][MAXN];
int N, M;
int hungary(int node)
{
int i;
for(i=1; i<=M; i++)
if(!tag[i] && f[node][i])
{
tag[i]=1;
if(!match[i] || hungary(match[i]))
{
match[i]=node;
return 1;
}
}
return 0;
}
int main(void)
{
int i, cnt, ns, t, j;
while(scanf("%d%d", &N, &M)!=EOF)
{
memset(f, 0, sizeof(f));
memset(match, 0, sizeof(match));
#ifdef LOL_DEBUG
puts("reading data....");
#endif
for(i=1; i<=N; i++)
{
scanf("%d", &ns);
for(j=0; j<ns; j++)
scanf("%d", &t), f[i][t]=1;
}
#ifdef LOL_DEBUG
puts("invoking hungary()...");
#endif
cnt=0;
for(i=1; i<=N; i++)
{
memset(tag, 0, sizeof(tag));
if(hungary(i))
cnt++;
}
printf("%d\n", cnt);
}
return 0;
}