匈牙利算法注重在于增广路的查找。图的两个点可以分为两个集合A,B。A B集合之间的关系就是图的边。现在让图的边数值最大。对每一个点找增广路(就是看每一边能不能扩展原本的路径n+1),在查找第i个点的增广路时候,如果B集合K的点已经被别人选择了,则尝试让B的点能否在不损失原本路径的长度上让位置给当前节点,那么需要回溯K的父亲节点,看他有没有其他增广路径长度为n并且可以让第i个点的增广路符合。注重腾空间过程,记住每一轮都要初始化used数组 并且在fin函数中走过一次就要设值为1不然会死循环
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int map[1000][1000],f[1000],used[1000];
int n,m,bian;
int Fin(int x)
{
for(int i=1;i<=m;i++)
{
if(map[x][i]==1&&used[i]==0)
{
used[i]=1;
if(f[i]==0||Fin(f[i]))
{
f[i]=x;
return 1;
}
}
}
return 0;
}
int main()
{
scanf("%d %d %d",&n,&m,&bian);
memset(f,0,sizeof(f));
memset(map,0,sizeof(map));
for(int i=1;i<=bian;i++)
{
int a,b;
scanf("%d %d",&a,&b);
map[a][b]=1;
}
int ans=0;
for(int i=1;i<=n;i++)
{
memset(used,0,sizeof(used));
if(Fin(i)) ans++;
}
printf("%d\n",ans);
return 0;
}