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

一:匈牙利算法的原理:

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


 

//求更好的解释  求地址

你可能感兴趣的:(二分图最大匹配问题之匈牙利算法)