//简单的匈牙利算法模板题。。题意是奶牛在自己喜欢的牛栏里才有最大的产量,有N头牛,M个牛栏。求最大产量。
//如果mk[i]=0表示未访问过,如果为1表示访问过
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn=500;
int mk[maxn];
int nx,ny; //X和Y集合中顶点的个数
int g[maxn][maxn]; //邻接矩阵, X集合和Y集合中顶点间边的信息
int cx[maxn],cy[maxn];
int path(int u)
{
 for(int v=1;v<=ny; v++) //考虑所有Yi顶点v
 {
  if(g[u][v]&&!mk[v])
  {
   mk[v]=1;

   if(cy[v]==-1||path(cy[v]))
   {
    cx[u] = v; //把v匹配给u
    cy[v] = u; //把u匹配给v
    return 1; //找到可增广路
   }
  }
 }
 return 0 ; //如果不存在从u出发的增广路
}
int MaxMatch() //求二部图最大匹配的匈牙利算法
{
 int res=0;
 int i;
 memset(cx,0xff,sizeof(cx)) ;
 memset(cy,0xff,sizeof(cy)) ;
 for(i=1;i<=nx;i++)
 {
  if(cx[i]==-1) //从每个未盖点出发进行寻找增广路
  {
   memset(mk,0,sizeof(mk));
   res+=path(i); //每找到一条增广路,可使得匹配数加1
  }
 }
 return res;
}
int main()
{
 int n,m;
 int i,j;
 int num,ans;
 while(scanf("%d%d",&n,&m)!=EOF)
 {
  nx=n;ny=m;
  memset(g,0,sizeof(g));
  for(i=1;i<=n;i++)
  {
   scanf("%d",&num);
   for(j=1;j<=num;j++)
   {
    scanf("%d",&ans);
    g[i][ans]=1;
   }
  }
  printf("%d\n",MaxMatch());
 }
 return 0;
}

posted on 2012-01-29 15:29  →木头←  阅读(134)  评论(0编辑  收藏  举报