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;
}
posted @ 2023-04-17 19:34  N0zoM1z0  阅读(10)  评论(0编辑  收藏  举报