参考文章:
https://blog.csdn.net/qq_37457202/article/details/80161274
https://blog.csdn.net/u013384984/article/details/90718287
https://blog.csdn.net/mengxiang000000/article/details/50888589
#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
vector<int> mp[1505]; //各结点之间的邻接表
int vis[1505]; //每次查找增广路时,结点的访问状态
int match[1505]; //各结点的匹配结点
//寻找增广路
int find(int x)
{
for (int i = 0; i < mp[x].size(); i++)
{
int v = mp[x][i];
if (vis[v] == 0)
{
vis[v] = 1;
//当前结点没有匹配结点,或者能从其匹配结点出发,找到增广路
if (match[v] == -1 || find(match[v]))
{
match[v] = x; //设置匹配结点
return 1;
}
}
}
return 0;
}
int main()
{
int n;
while (cin >> n)
{
for (int i = 0; i < n; i++) //清空vector
{
mp[i].clear();
}
for (int i = 0; i < n; i++)
{
int u, num;
cin >> u;
cin.get();
cin.get();
cin >> num;
cin.get();
for (int j = 0; j < num; j++)
{
int v;
cin >> v;
mp[u].push_back(v);
mp[v].push_back(u);
}
}
int sum = 0;
memset(match, -1, sizeof(match));
for (int i = 0; i < n; i++)
{
memset(vis, 0, sizeof(vis));
if (find(i)) //如果有增广路,匹配数加一
sum++;
}
cout << sum / 2 << endl; //最小顶点覆盖 == 最大匹配(双向图)/ 2
}
return 0;
}