【二分图】特别接地气的讲解匈牙利算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

既然是解决二分图的最大匹配问题的算法,那么,就先来了解一下二分图是什么(来自度娘):

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。

举个例子:下面就是一个二分图,我们可以发现,这个图上的顶点都被涂上了蓝(好像有点像紫色)或绿两种颜色,并且没有同色的相邻顶点,这种判断二分图的方法叫做染色法

既然了解了二分图,那我们就可以开始学习匈牙利算法了。

但是,教科书上的专业语言真的让人很头大,要是看教科书,我可能这辈子都学不会匈牙利算法,但是我发现了一个很有趣的方法

假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感,如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在让我们无视掉所有的单相思,你拥有的大概就是下面这样一张关系图,每一条连线都表示互有好感。

现在,你需要尽量多的撮合CP,用匈牙利算法,就是这样的:

一、先给1号男嘉宾找对象,你最先找到的便是1号女嘉宾,所以就先把他们连在一起

二、 接着,你要给2号男嘉宾找对象,就找到了2号女嘉宾,就把他们也连到一起

 三、接着,到了3号男嘉宾,可是1号女嘉宾已经名花有主了,那我们就尝试给1号男嘉宾另分配一个女嘉宾

 

 与1号男嘉宾相连的第二个女生是2号女嘉宾,但是2号女嘉宾也有主了,我们再试着给2号男嘉宾重新找个妹子(同上)

 

三、这个时候我们发现,2号男嘉宾还可以找3号女嘉宾,这样问题就解决了,我们就只需要:

 2号男嘉宾可以找3号女嘉宾                 1号男嘉宾可以找2号女嘉宾                3号男嘉宾可以找1号女嘉宾

 

所以目前的结果就是这样:

四、接下来是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 }

 

posted @ 2019-07-25 15:47  夜雨声烦fff  阅读(104)  评论(0编辑  收藏