您的位置:首页 > 其它

二分图最大匹配问题之匈牙利算法

2012-08-11 10:34 260 查看
一:匈牙利算法的原理:

从当前的匹配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;

}


//求更好的解释 求地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: