P1894
[USACO4.2]完美的牛栏The Perfect Stall
题目描述
农夫约翰上个星期刚刚建好了他的新牛棚,他使用了最新的挤奶技术。
不幸的是,由于工程问题,每个牛栏都不一样。
第一个星期,农夫约翰随便地让奶牛们进入牛栏,但是问题很快地显露出来:每头奶牛都只愿意在她们喜欢的那些牛栏中产奶。
上个星期,农夫约翰刚刚收集到了奶牛们的爱好的信息(每头奶牛喜欢在哪些牛栏产奶)。
一个牛栏只能容纳一头奶牛,当然,一头奶牛只能在一个牛栏中产奶。
给出奶牛们的爱好的信息,计算最大分配方案。
输入格式
第一行为两个整数,\(n\) 和 \(m\)。\(n\) 是农夫约翰的奶牛数量,\(m\) 是新牛棚的牛栏数量。
第二行到第 \(n+1\) 行 一共 \(n\) 行,每行对应若干个整数一只奶牛。第一个数字 \(s_i\) 是这头奶牛愿意在其中产奶的牛栏的数目。后面的 \(s_i\) 个数表示这些牛栏的编号。牛栏的编号限定在区间 \([1,m]\) 中,在同一行,一个牛栏不会被列出两次。
输出格式
只有一行,为一个整数,表示最多能分配到的牛栏的数量。
样例 #1
样例输入 #1
5 5
2 2 5
3 2 3 4
2 1 5
3 1 2 5
1 2
样例输出 #1
4
提示
\(0\le n,m\le 200\),\(0\le s_i\le m\)。
匈牙利算法模板题
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int g[205][205];
int vis[205],match[205],ans;
bool find(int x) {
for(int i=1; i<=m; i++) {
if(vis[i]||g[x][i]==0)continue;
vis[i]=1;
int t=match[i];
if(t==0||find(t)) {
match[i]=x;
return true;
}
}
return false;
}
signed main() {
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1; i<=n; i++) {
int s,x;
cin>>s;
for(int j=1; j<=s; j++) {
cin>>x;
g[i][x]=1;
}
}
for(int i=1; i<=n; i++) {
memset(vis,0,sizeof(vis));
if(find(i))ans++;
}
cout<<ans<<"\n";
return 0;
}