邻接表写法:
注意,假设给定的是N头牛,M个单间,N和M的最大值是都是200的话,那么对于我们数组邻接表而言,我们是用邻接表存储的是边,所以最多会有200 * 200条边,而存的不是点。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10, M = 4e4 + 10;
int h[N], e[M], ne[M], idx; //h[i]: 表示第i头奶牛愿意生产的单间的头结点!
int n, m;
bool st[N]; //标记该点是否在这一轮中被访问过了!
int match[N]; //match[i]=j:表示第i个房间是给第j号牛的!
void add (int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
bool find(int u)
{
for (int i=h[u]; ~i; i = ne[i])
{
int j = e[i];
if (!st[j])
{
st[j] = true;
if (!match[j] || find(match[j]))
{
match[j] = u;
return true;
}
}
}
return false;
}
int main()
{
cin >> n >> m;
memset (h, -1, sizeof (h));
for (int i=1; i <= n; i ++)
{
int k;
scanf ("%d", &k);
while (k --)
{
int x;
scanf ("%d", &x);
add (i, x);
}
}
int res = 0;
for (int i=1; i <= n; i++)
{
memset (st, 0, sizeof (st));
if (find(i))
res ++;
}
printf ("%d", res);
return 0;
}
邻接矩阵写法:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2e2 + 10;
int g[N][N]; //g[i][j] = x:表示第i头牛到第j号房是否愿意生产!
int n, m;
bool st[N*2]; //标记该点是否是访问过了!
int match[N];
bool dfs (int u)
{
for (int i=1; i <= m; i ++) //每头牛!
{
if (!st[i] && g[u][i])
{
st[i] = true;
if (!match[i] || dfs(match[i]))
{
match[i] = u;
return true;
}
}
}
return false;
}
int main()
{
cin >> n >> m;
for (int i=1; i <= n; i ++) //枚举每头牛!
{
int cnt=0;
cin >> cnt;
while (cnt --)
{
int x;
cin >> x;
g[i][x] = 1; //表示从i-->x;
}
}
int res=0;
for (int i=1; i <= n; i ++) //遍历每头牛!
{
memset (st, false, sizeof (st));
if (dfs (i)) res ++;
}
cout << res << endl;
return 0;
}