计蒜客--郊游

蒜头君成为了计蒜客附属幼儿园的一名老师,一个阳光明媚的周末,蒜头君带领着小朋友们去野外郊游。一共有 2n2n 个小朋友,正好是 nn 个男孩和 nn 个女孩。蒜头君让小朋友分组玩游戏,每组一个男孩和一个女孩,但是有些女孩比较讨厌某些男孩,不愿意和他们分在一组,男孩觉得和谁分在一组都无所谓。你能告诉蒜头君最多能分成多少个组吗?

输入格式

第一行输入一个整数 nn,表示有 nn 个男孩和 nn 个女孩。

接下来 nn 行,对于第 i + 1i+1 行,首先输入一整数 k_iki,后面输入 k_iki 个用空格隔开的整数 a_{i,j}ai,j。表示第 ii 个女孩愿意在一组的男孩列表。

数据约定:

对于 30% 的数据:1 \le n \le 101n100 \le k_i \le n0kin1 \le a_{ij} \le n1aijn

对于 60% 的数据:1 \le n \le 1001n1000 \le k_i \le n0kin1 \le a_{ij} \le n1aijn

对于 100% 的数据:1 \le n \le 100001n100000 \le k_i \le n0kin0 \le k_1 + k_2 + k_3 + \cdots + k_n \le 200000k1+k2+k3++kn200001 \le a_{ij} \le n1aijn

输出格式

输出一个整数,表示最多能组成的队伍数量。

样例输入
4
1 2
1 2
3 1 2 3
4 1 2 3 4
样例输出
3

匈牙利算法

#include<bits/stdc++.h>
using namespace std;
int v[10002]={0},g[10002];
vector<int> a[10002];
int find(int x)
{
	for(int i=0;i<a[x].size();i++)//遍历所有能够交友的男票
	{
		if(v[a[x][i]]==0)//如果a[x][i]没有被前面临时调整
		{
			v[a[x][i]]=1;//标记被临时调整
			if(g[a[x][i]]==0||find(g[a[x][i]]))//如果a[x][i]没有女票,或者递归下去看是否能够调整,让这个女孩换个男票
                        {
				g[a[x][i]]=x;//可以调整,更新g[男]=新女票
				return 1;
			 } 
		}
	}
	return 0;
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int m,x;
		cin>>m;
		for(int j=1;j<=m;j++)
		{
			cin>>x;
			a[i].push_back(x);
		}
	}
	int sum=0;
	for(int i=1;i<=n;i++)
	{
		memset(v,0,sizeof(v));
		if(find(i))
		{
			sum++;
		}
	}
	cout<<sum;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值