【二分図マッチング】乳牛配分
, 。 , , 。 , , : 。 , ( )。 , , 。
, 。
,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);
}