【二分図マッチング】乳牛配分


  
                  ,           。    ,      ,        。     ,               ,           :                     。    ,                   (             )。            ,  ,              。 
           ,        。 

    
        ,N (0 <= N <= 200)   M (0 <= M <= 200) 。N           ,M          。 
     N+1     N  ,        。      (Si)                    (0 <= Si <= M) 。    Si            。           (1..M)  ,    ,           。 

    
    。      ,              。 

SAMPLE INPUT 
5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2 
SAMPLE OUTPUT 
4

これはハンガリーのアルゴリズムの入門問題で、比較的簡単ではありません.
Accode:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <bitset>

const char fi[] = "stall4.in";
const char fo[] = "stall4.out";
const int maxN = 210;
const int MAX = 0x3fffff00;
const int MIN = -MAX;

struct Edge {int dest; Edge *next; };

Edge *edge[maxN];
int Link[maxN];
std::bitset <maxN> marked;
int n, m, t, c, ans;

  void init_file()
  {
    freopen(fi, "r", stdin);
    freopen(fo, "w", stdout);
  }

  inline void insert(int u, int v)
  {
    Edge *p = new Edge;
    p -> dest = v;
    p -> next = edge[u];
    edge[u] = p;
  }

  void readdata()
  {
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n + 1; ++i)
    {
      scanf("%d", &t);
      for (; t; --t)
      {
        scanf("%d", &c);
        insert(i, c);
      }
    }
  }

  bool Find(int u)
  {
    for (Edge *p = edge[u]; p; p = p -> next)
    {
      int v = p -> dest;
      if (marked.test(v)) continue;
      else marked.set(v);
      if (!Link[v] || Find(Link[v]))
      {
        Link[v] = u;
        return true;
      }
    }
    return false;
  }

  void work()
  {
    for (int i = 1; i < n + 1; ++i)
    {
      marked.reset();
      if (Find(i)) ++ans;
    }
    printf("%d", ans);
  }

int main()
{
  init_file();
  readdata();
  work();
  exit(0);
}