【二分圖】特別接地氣的講解匈牙利算法

匈牙利算法是由匈牙利數學家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 }
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息