纯匈牙利算法模板,很水,但是需要理解。
这题把行列看做需要匹配的对象。把最小的覆盖数转化成求匹配成功数。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=505;
int Mao[maxn][maxn];//储存点
int vis[maxn];//记录是否访问过列
int match[maxn];//记录列匹配的行的标号
int n,k,sum=0;
bool dfs(int x)
{
for(int y=1;y<=n;y++)
{
if(!vis[y] && Mao[x][y])//如果没有访问过并且这个障碍需要被消除
{
vis[y]=1;
if(dfs(match[y]) || match[y]==0)//y已经匹配到一个x,于是继续搜索看x是否能匹配别的y。或者这个y没有匹配过。
{
match[y]=x;//条件成立就记录匹配成功的x
//cout << match[y] << ":" << x << endl;
return true;
}
}
}
return false;
}
int main()
{
memset(Mao,0,sizeof(Mao));
memset(match,0,sizeof(match));
cin >> n >> k;
int a,b;
for(int i=1;i<=k;i++)
{
cin >> a >> b;
Mao[a][b]=1;
}
for(int x=1;x<=n;x++)
{
memset(vis,0,sizeof(vis));//每次DFS一个行都要清零一次列的访问标记
if(dfs(x)) sum++;//匹配成功就会++
}
cout << sum << endl;//成功匹配数=最小覆盖数
return 0;
}