匈牙利算法是由匈牙利数学家Edmonds于1965年提出,于是得名。匈牙利算法是基于Hall定理中充分性证实的思想,它是部图匹配最多见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。算法
既然是解决二分图的最大匹配问题的算法,那么,就先来了解一下二分图是什么(来自度娘):学习
二分图又称做二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,若是顶点V可分割为两个互不相交的子集(A,B),而且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不一样的顶点集(i in A,j in B),则称图G为一个二分图。spa
举个例子:下面就是一个二分图,咱们能够发现,这个图上的顶点都被涂上了蓝(好像有点像紫色)或绿两种颜色,而且没有同色的相邻顶点,这种判断二分图的方法叫作染色法.net
既然了解了二分图,那咱们就能够开始学习匈牙利算法了。code
可是,教科书上的专业语言真的让人很头大,要是看教科书,我可能这辈子都学不会匈牙利算法,可是我发现了一个颇有趣的方法对象
假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每一个人均可能对多名异性有好感,若是一对男女互有好感,那么你就能够把这一对撮合在一块儿,如今让咱们无视掉全部的单相思,你拥有的大概就是下面这样一张关系图,每一条连线都表示互有好感。blog
如今,你须要尽可能多的撮合CP,用匈牙利算法,就是这样的:get
1、先给1号男嘉宾找对象,你最早找到的即是1号女嘉宾,因此就先把他们连在一块儿数学
2、 接着,你要给2号男嘉宾找对象,就找到了2号女嘉宾,就把他们也连到一块儿io
3、接着,到了3号男嘉宾,但是1号女嘉宾已经名花有主了,那咱们就尝试给1号男嘉宾另分配一个女嘉宾
与1号男嘉宾相连的第二个女生是2号女嘉宾,可是2号女嘉宾也有主了,咱们再试着给2号男嘉宾从新找个妹子(同上)
3、这个时候咱们发现,2号男嘉宾还能够找3号女嘉宾,这样问题就解决了,咱们就只须要:
2号男嘉宾能够找3号女嘉宾 1号男嘉宾能够找2号女嘉宾 3号男嘉宾能够找1号女嘉宾
因此目前的结果就是这样:
4、接下来是4号男嘉宾,很遗憾,按照第三步的方法咱们无法给4号男嘉宾腾出来一个女嘉宾
因此匈牙利算法的基本原则即是:有机会就上,没机会创造机会也要上
模板以下:
1 bool dfs(int x){ 2 int i, j; 3 for (j=1; j<=m; j++){ //扫描每一个妹子 4 if (line[x][j] && !used[j]){ //若是有好感而且尚未标记过 5 used[j]=1; 6 if (girl[j] == 0 || dfs(girl[j])) { //名花无主或者能腾出个位置来 7 girl[j]=x; 8 return true; 9 } 10 } 11 } 12 return false; 13 }
而主程序咱们就只须要循环一下就行了:
1 for (i=1;i<=n;i++) 2 { 3 memset(used,0,sizeof(used)); //在每一步中清空 4 if (dfs(i)) ans+=1; 5 }