匈牙利算法注重在于增广路的查找。图的两个点可以分为两个集合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; }