一:匈牙利算法的原理:
从当前的匹配M(如果木有匹配,则取初始化匹配M为空集)出发,检查每一个未盖点,然后从它出发寻找可增广路,找到可增广路,则沿着这条可增广路进行扩充,直到不存在可增广路为止。
二:根据从未盖点出发寻找可增广路搜索的方法,可以分成:1.DFS增广 2.BFS增广 3.多增广(Hopcroft-Karp算法)
采用DFS思想搜索可增广路并求出最大匹配的代码如下:
#define MAX 101//MAX为表示X集合和Y集合顶点个数最大值的符号常量
int vis[MAX] ;//记录顶点访问状态的数组,为1时表示已经访问过,为0时表示未被访问过
int nx,ny; //表示集合X,Y集合中的个数
int map[MAX][MAX]; //邻接矩阵,为1时表示Xi 和Yj有边相连
int dx[MAX],dy[MAX];//dx[i]表示最终求得最大匹配中与Xi 匹配的Y顶点,dy[]同理
int DFS(int v)//这种增广使得当前匹配数增加1
{
for(int i=0;i<ny;i++)//考虑到所有Yi 顶点i
if(map[v][i]&&!vis[i])//v与i 相连并且没有访问过
{
vis[i]=1;//访问i 标记为1
if(dy[i]==-1||DFS(dy[i]))//如果i 没有匹配,或者i 已经匹配了不过从dy[i]出发可以找到一条增广路
{//注意 如果i 没有匹配 那么后面的DFS(dy[i])这个递归过程不会运行
dx[v]=i;//把i 匹配给v
dy[i]=v;//把v 匹配给i
return 1;
}
}
return 0;//表示不存在从v出发的增光路
}
int Hungary()
{
int ans=0;//求得的最大匹配数
memset(dx,0xff,sizeof(dx));//初始化为-1
memset(dy,0xff,sizeof(dy));//初始化为-1
for(int i=0;i<=nx;i++)//for结束意味着寻找增光路结束,最大匹配诞生
if(dx[i]==-1)//如果是未盖点则出发进行寻找增广路
{
memset(vis,0,sizeof(vis));//初始化
ans+=DFS(i);//没找到一条增广路则匹配数累加1
}
return ans;
}
//求更好的解释 求地址