蒜头君成为了计蒜客附属幼儿园的一名老师,一个阳光明媚的周末,蒜头君带领着小朋友们去野外郊游。一共有 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 101≤n≤10,0 \le k_i \le n0≤ki≤n,1 \le a_{ij} \le n1≤aij≤n。
对于 60% 的数据:1 \le n \le 1001≤n≤100,0 \le k_i \le n0≤ki≤n,1 \le a_{ij} \le n1≤aij≤n。
对于 100% 的数据:1 \le n \le 100001≤n≤10000,0 \le k_i \le n0≤ki≤n,0 \le k_1 + k_2 + k_3 + \cdots + k_n \le 200000≤k1+k2+k3+⋯+kn≤20000,1 \le a_{ij} \le n1≤aij≤n。
输出格式
输出一个整数,表示最多能组成的队伍数量。
样例输入
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;
}